"""
CLEAN MINIMAL SALES DASHBOARD - Start from scratch
Focus: Get the data RIGHT first, then add features
"""

from flask import Flask, session, redirect, url_for, request, jsonify, render_template, Response
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user
from google_auth_oauthlib.flow import Flow
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from google.auth.transport.requests import Request
import gspread
import pandas as pd
import os
import re
import json
import csv
import io
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from urllib.parse import urlencode, quote_plus
from datetime import timedelta, datetime
import time
from functools import wraps
import threading
import priority_actions_helper as pah
import client_intelligence_helper as cih
from data_validation import DataValidator, validate_objectives_sheet

# ============================================================================
# CONFIG
# ============================================================================

app = Flask(__name__)

def env_bool(name, default=False):
    value = os.getenv(name)
    if value is None:
        return default
    return value.strip().lower() in ('1', 'true', 'yes', 'on')

APP_ENV = os.getenv('APP_ENV', os.getenv('FLASK_MODE', 'development')).strip().lower()
if APP_ENV not in ('development', 'production'):
    APP_ENV = 'development'

IS_PRODUCTION = APP_ENV == 'production'
BASE_URL = os.getenv('BASE_URL', 'https://sales.globalerc.pt' if IS_PRODUCTION else 'http://localhost:5000').rstrip('/')
OAUTH_REDIRECT_URI = f"{BASE_URL}/oauth2callback"

app.secret_key = os.getenv('SECRET_KEY', 'dev-only-change-me')
app.config['SESSION_COOKIE_SECURE'] = env_bool('SESSION_COOKIE_SECURE', IS_PRODUCTION)
app.config['SESSION_COOKIE_HTTPONLY'] = True
app.config['SESSION_COOKIE_SAMESITE'] = os.getenv('SESSION_COOKIE_SAMESITE', 'Lax')
app.config['PREFERRED_URL_SCHEME'] = os.getenv('PREFERRED_URL_SCHEME', 'https' if IS_PRODUCTION else 'http')
app.permanent_session_lifetime = timedelta(minutes=60)
app.config['TEMPLATES_AUTO_RELOAD'] = not IS_PRODUCTION
if not IS_PRODUCTION:
    app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0

if IS_PRODUCTION:
    os.environ.pop('OAUTHLIB_INSECURE_TRANSPORT', None)
else:
    os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'

CLIENT_SECRETS_FILE = "credentials.json"
DEFAULT_SPREADSHEET_ID = "1ayEGU0h_R7CY55COC1U94-p0rJch109YBGvezjYjHWw"

SMTP_ENABLED = os.getenv('SMTP_ENABLED', 'false').lower() == 'true'
SMTP_SERVER = os.getenv('SMTP_SERVER', 'smtp.gmail.com')
SMTP_PORT = int(os.getenv('SMTP_PORT', '587'))
SMTP_USERNAME = os.getenv('SMTP_USERNAME', '')
SMTP_PASSWORD = os.getenv('SMTP_PASSWORD', '')
VISIT_REPORT_NOTIFICATION_TO = os.getenv('VISIT_REPORT_NOTIFICATION_TO', '')

# ============================================================================
# INVENTORY MODULE CONFIGURATION (Separate System)
# ============================================================================
INVENTORY_SPREADSHEET_ID = "1_r06d4IolTc65P7KLN8XSq2ikG4gf-MG"
INVENTORY_FOLDER_ID = "1aEmu5bRDYwAZG0ZwUgOxTJ_JnJobJbQK"
INVENTORY_CONFIG_FILE = "inventory_config.json"
INVENTORY_COLUMNS = [
    'Linha',
    'Quantidade em stock',
    'Tipo',
    'Ref',
    'Modelo',
    'Submodelo',
    'Tipo de tampa',
    'Medida',
    'Tipo de Medida',
    'Madeira',
    'Laminado',
    'Cor',
    'Acabamento',
    'Zinco/Inox',
    'Estofo',
    'Tecido',
    'Cor Tecido',
    'Renda',
    'Conjunto',
    'Asas',
    'Qtd Asas',
    'Cruz/Cristo',
    'Fecho',
    'Acessórios',
    'Extras/Observações',
    'Cliente'
]

def load_inventory_config():
    if not os.path.exists(INVENTORY_CONFIG_FILE):
        return None
    try:
        with open(INVENTORY_CONFIG_FILE, 'r') as f:
            data = json.load(f)
        spreadsheet_id = data.get('spreadsheet_id')
        return spreadsheet_id if spreadsheet_id else None
    except Exception as e:
        print(f"[INVENTORY] Warning: Could not read inventory config: {e}")
        return None

def save_inventory_config(spreadsheet_id):
    try:
        with open(INVENTORY_CONFIG_FILE, 'w') as f:
            json.dump({
                'spreadsheet_id': spreadsheet_id,
                'updated_at': datetime.utcnow().isoformat() + 'Z'
            }, f)
    except Exception as e:
        print(f"[INVENTORY] Warning: Could not save inventory config: {e}")

_inventory_config_id = load_inventory_config()
if _inventory_config_id:
    INVENTORY_SPREADSHEET_ID = _inventory_config_id

# ============================================================================
# ROLE-BASED ACCESS CONTROL (RBAC) CONFIGURATION
# ============================================================================

# Define email lists for each role
ADMIN_EMAILS = {
    "de.globalerc@gmail.com",
    "op.globalerc@gmail.com",
    "df.globalerc@gmail.com",
}

COMMERCIAL_EMAILS = {
    "joseamor.globalerc@gmail.com",
    "helderoliveira.globalerc@gmail.com",
    "tiagovibecoding@gmail.com",  # Test user
}

WAREHOUSE_EMAILS = {
    "teste.armazem@gmail.com",  # Test warehouse user
    # Add warehouse team members here
    # Example: "warehouse1@globalerc.com",
    # Example: "warehouse2@globalerc.com",
}

# Legacy mapping for backward compatibility
# Roles: admin, viewer, comercial, warehouse
USERS_ROLES = {
    # Admins - access to all information, can edit data
    "de.globalerc@gmail.com": "admin",
    "op.globalerc@gmail.com": "admin",
    "df.globalerc@gmail.com": "admin",

    # Viewers - view-only access to all data
    "adm.globalerc@gmail.com": "viewer",
    
    # Comercials - restricted view of their own data only
    "joseamor.globalerc@gmail.com": "comercial",
    "helderoliveira.globalerc@gmail.com": "comercial",
    "tiagovibecoding@gmail.com": "comercial",  # Test user - sees José Amor's data
    
    # Warehouse - access to inventory management
    # Add warehouse team here: "warehouse1@globalerc.com": "warehouse",
}

# Legacy access map for backward compatibility with comercial role filtering
SALES_ACCESS_MAP = {
    "joseamor.globalerc@gmail.com": ["José Amor"],
    "helderoliveira.globalerc@gmail.com": ["Hélder Oliveira"],
    "de.globalerc@gmail.com": ["Exportação", "Firma"],
    "df.globalerc@gmail.com": ["Firma"],
    "tiagovibecoding@gmail.com": ["José Amor"],  # Test user - restricted to José Amor's data only
}

# Commission rates by comercial
COMMISSION_RATES = {
    "José Amor": 0.085,
    "Hélder Oliveira": 0.07,
}
SCOPES = [
    'https://www.googleapis.com/auth/spreadsheets',
    'https://www.googleapis.com/auth/drive',
    'https://www.googleapis.com/auth/userinfo.email',
    'https://www.googleapis.com/auth/userinfo.profile',
    'openid'
]

# ============================================================================
# ENVIRONMENT CONFIGURATION (Development vs Production)
# ============================================================================
# APP_ENV drives runtime behavior. Keep FLASK_MODE alias for backward compatibility in existing UI logic.
FLASK_MODE = APP_ENV
SERVER_URL = BASE_URL

if IS_PRODUCTION:
    # Production runtime should be gunicorn on loopback behind nginx.
    FLASK_HOST = os.getenv('FLASK_HOST', '127.0.0.1')
    FLASK_PORT = int(os.getenv('FLASK_PORT', '8000'))
    print(f"[CONFIG] Running in PRODUCTION mode -> {SERVER_URL}")
else:
    # Keep localhost as default, but allow LAN sharing without ngrok via FLASK_HOST=0.0.0.0
    FLASK_HOST = os.getenv('FLASK_HOST', '127.0.0.1')
    FLASK_PORT = int(os.getenv('FLASK_PORT', '5000'))
    print(f"[CONFIG] Running in DEVELOPMENT mode -> {SERVER_URL}")

REDIRECT_URI_BASE = OAUTH_REDIRECT_URI

login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
users = {}

# ============================================================================
# CACHING SYSTEM - Dramatically improves performance
# ============================================================================

DATA_CACHE = {}
CACHE_TTL = 300  # 5 minutes cache lifetime

def get_cache_key(prefix='data'):
    """Generate cache key based on user session and spreadsheet"""
    spreadsheet_id = session.get('spreadsheet_id') or DEFAULT_SPREADSHEET_ID
    user_email = session.get('user_email', 'anonymous')
    return f"{prefix}:{spreadsheet_id}:{user_email}"

def get_cached_data(key):
    """Retrieve data from cache if valid"""
    if not IS_PRODUCTION:
        return None

    if key in DATA_CACHE:
        cached_item = DATA_CACHE[key]
        age = time.time() - cached_item['timestamp']
        if age < CACHE_TTL:
            print(f"[CACHE HIT] {key} (age: {age:.1f}s)")
            return cached_item['data']
        else:
            print(f"[CACHE EXPIRED] {key} (age: {age:.1f}s)")
            del DATA_CACHE[key]
    print(f"[CACHE MISS] {key}")
    return None

def set_cached_data(key, data):
    """Store data in cache with timestamp"""
    if not IS_PRODUCTION:
        return

    DATA_CACHE[key] = {
        'data': data,
        'timestamp': time.time()
    }
    print(f"[CACHE SET] {key}")

def clear_cached_data(key):
    """Clear specific cached data"""
    if key in DATA_CACHE:
        del DATA_CACHE[key]
        print(f"[CACHE CLEARED] {key}")
        return True
    return False

def clear_cache(pattern=None):
    """Clear cache entries matching pattern, or all if pattern is None"""
    global DATA_CACHE
    if pattern:
        keys_to_delete = [k for k in DATA_CACHE.keys() if pattern in k]
        for key in keys_to_delete:
            del DATA_CACHE[key]
        print(f"[CACHE CLEAR] Removed {len(keys_to_delete)} entries matching '{pattern}'")
    else:
        count = len(DATA_CACHE)
        DATA_CACHE = {}
        print(f"[CACHE CLEAR] Removed all {count} entries")

def normalize_email(user_email):
    if not user_email:
        return None
    return user_email.strip().lower()

# Helper function to get user role based on email
def get_user_role(user_email):
    """
    Assign role based on email address.
    Returns: 'admin', 'comercial', 'viewer', 'warehouse', or 'client'
    """
    normalized = normalize_email(user_email)
    
    # Check USERS_ROLES mapping first (legacy)
    if normalized in USERS_ROLES:
        return USERS_ROLES[normalized]
    
    # Check role-specific email sets
    if normalized in ADMIN_EMAILS:
        return 'admin'
    elif normalized in COMMERCIAL_EMAILS:
        return 'comercial'
    elif normalized in WAREHOUSE_EMAILS:
        return 'warehouse'
    else:
        return 'viewer'

# Helper function to check permissions
def has_permission(user_email, permission):
    """
    Check if user has a specific permission
    Permissions: 'view_all', 'edit_data', 'view_own'
    """
    role = get_user_role(user_email)
    if role == 'admin':
        return permission in ['view_all', 'edit_data', 'view_own']
    elif role == 'viewer':
        return permission in ['view_all', 'view_own']
    elif role == 'comercial':
        return permission in ['view_own']
    return False

# ============================================================================
# USER MODEL
# ============================================================================

class User(UserMixin):
    def __init__(self, id_, email=None, role=None):
        self.id = id_
        self.email = email
        self.role = role or 'client'  # Default to 'client' if not specified

@login_manager.user_loader
def load_user(user_id):
    return users.get(user_id)

# ============================================================================
# ROLE-BASED ACCESS CONTROL DECORATOR
# ============================================================================

def role_required(*allowed_roles):
    """
    Decorator to restrict access to routes based on user role.
    
    Usage:
        @app.route('/admin-only')
        @role_required('admin')
        def admin_route():
            return "Admin only"
        
        @app.route('/admin-or-commercial')
        @role_required('admin', 'commercial')
        def admin_or_commercial_route():
            return "Admin or Commercial"
    """
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            if not current_user.is_authenticated:
                return redirect(url_for('login'))
            
            if current_user.role not in allowed_roles:
                print(f"[RBAC] Access denied for user {current_user.email} with role '{current_user.role}' to {f.__name__}")
                return jsonify({'error': 'Access denied'}), 403
            
            return f(*args, **kwargs)
        return decorated_function
    return decorator

# ============================================================================

def get_redirect_uri_from_credentials():
    """Get registered redirect_uri from the credentials file"""
    try:
        import json
        with open(CLIENT_SECRETS_FILE) as f:
            creds = json.load(f)
            uris = creds.get('web', {}).get('redirect_uris', [])
            if uris:
                return uris[0]  # Return the first registered URI
    except Exception as e:
        print(f"[AUTH] Error reading credentials: {e}")
    return None

def get_flow(state=None):
    """Create OAuth flow using environment-derived redirect URI.

    If state is provided, bind it to the flow so callback validation is consistent.
    """
    try:
        redirect_uri = REDIRECT_URI_BASE
        # In development, bind callback to the exact host the user is using
        # (e.g., LAN IP) instead of forcing localhost.
        if not IS_PRODUCTION and request and request.host:
            scheme = request.headers.get('X-Forwarded-Proto', request.scheme)
            redirect_uri = f"{scheme}://{request.host}/oauth2callback"
        if not redirect_uri:
            # Fallback to credentials.json
            with open(CLIENT_SECRETS_FILE, 'r') as f:
                creds_config = json.load(f)
                redirect_uri = creds_config['web']['redirect_uris'][0]
    except RuntimeError:
        # Not in request context - use credentials.json
        with open(CLIENT_SECRETS_FILE, 'r') as f:
            creds_config = json.load(f)
            redirect_uri = creds_config['web']['redirect_uris'][0]
    
    print(f"[AUTH] Using redirect_uri: {redirect_uri}")
    
    flow = Flow.from_client_secrets_file(
        CLIENT_SECRETS_FILE, 
        scopes=SCOPES, 
        redirect_uri=redirect_uri
    )
    if state:
        flow.state = state
    # Request offline access to get refresh token
    flow.client_config['access_type'] = 'offline'
    return flow

def get_google_credentials():
    print(f"[CREDS] Checking session... has 'credentials'? {'credentials' in session}")
    if 'credentials' not in session:
        print("[CREDS] ERROR: No credentials in session")
        return None
    
    print("[CREDS] Found credentials in session")
    creds_data = session['credentials']
    print(f"[CREDS] Has refresh_token? {bool(creds_data.get('refresh_token'))}")
    print(f"[CREDS] Token: {creds_data.get('token', 'NONE')[:20] if creds_data.get('token') else 'NONE'}...")
    
    creds = Credentials.from_authorized_user_info(info=creds_data)
    
    print(f"[CREDS] Valid: {creds.valid}, Expired: {creds.expired}, Has refresh_token: {bool(creds.refresh_token)}")
    
    if not creds.valid:
        print("[CREDS] Credentials not valid")
        if creds.expired and creds.refresh_token:
            try:
                print("[CREDS] Attempting to refresh...")
                creds.refresh(Request())
                session['credentials'] = {
                    'token': creds.token,
                    'refresh_token': creds.refresh_token,
                    'token_uri': creds.token_uri,
                    'client_id': creds.client_id,
                    'client_secret': creds.client_secret,
                    'scopes': creds.scopes
                }
                print("[CREDS] Credentials refreshed successfully")
            except Exception as e:
                print(f"[CREDS] Error refreshing: {e}")
                return None
        else:
            print("[CREDS] Cannot refresh - either not expired or no refresh_token. Need re-login.")
            return None
    
    print("[CREDS] Credentials are valid and ready to use")
    return creds


# ============================================================================
# DATA HELPERS - SIMPLE & CLEAN
# ============================================================================

def parse_number(value):
    """Parse numbers from Google Sheets - handle European format."""
    if pd.isna(value) or value == '' or value is None:
        return 0.0
    
    if isinstance(value, (int, float)):
        return float(value)
    
    # Convert to string
    s = str(value).strip()
    if not s or s.lower() in ['nan', 'none', 'null', '']:
        return 0.0

    # Remove currency symbols and spaces
    s = s.replace('€', '').replace('$', '').replace(' ', '').strip()
    
    # European format: 6.005.182,69 -> 6005182.69
    # US format: 6,005,182.69 -> 6005182.69
    # Simple format: 6005182.69 or 6005182,69
    
    # Count dots and commas
    dots = s.count('.')
    commas = s.count(',')
    
    if dots > 0 and commas > 0:
        # Both exist - last one is decimal separator
        last_dot_pos = s.rfind('.')
        last_comma_pos = s.rfind(',')
        
        if last_comma_pos > last_dot_pos:
            # European: dots=thousands, comma=decimal
            s = s.replace('.', '').replace(',', '.')
        else:
            # US: commas=thousands, dot=decimal
            s = s.replace(',', '')
    elif commas > 0:
        # Only commas
        parts = s.split(',')
        if len(parts) == 2 and len(parts[1]) == 2:
            # Decimal comma: 1234,56
            s = s.replace(',', '.')
        else:
            # Thousands: 1,234 or multiple commas
            s = s.replace(',', '')
    # else: only dots or nothing - leave as is
    
    try:
        return float(s)
    except:
        print(f"[PARSE ERROR] Could not parse: '{value}' -> '{s}'")
        return 0.0


def filter_urnas_family_rows(df, familia_col):
    """Return only URNAS rows using STRICT family matching - EXACTLY 'urna' or 'urnas' only.
    
    CRITICAL BUSINESS RULE: Only products with familia = 'URNAS', 'Urnas', 'urnas', 'URNA', 'Urna', 'urna'
    (case-insensitive exact match). Products like 'Urna Nova', 'Urnas Antigas', etc. are NOT urnas 
    and must be EXCLUDED.
    """
    if df is None or df.empty or not familia_col or familia_col not in df.columns:
        return df

    # Normalize: strip whitespace, convert to lowercase, collapse multiple spaces
    family_series = df[familia_col].astype(str).str.strip().str.lower().str.replace(r'\s+', ' ', regex=True)

    # STRICT RULE: familia must be EXACTLY 'urna' or 'urnas' (case-insensitive) - nothing else!
    # Matches: URNAS, Urnas, urnas, URNA, Urna, urna
    # Rejects: URNAS NOVAS, Urna Nova, Urnas Antigas, etc.
    strict_mask = family_series.isin(['urna', 'urnas'])
    return df[strict_mask]


def fetch_data_uncached():
    """Fetch data from Google Sheets - use PANDAS for parsing only."""
    print("\n[FETCH] Starting data fetch...")
    
    creds = get_google_credentials()
    if not creds:
        print("[FETCH] ERROR: No credentials")
        return None
    
    print("[FETCH] Credentials OK")
    
    SPREADSHEET_ID = session.get('spreadsheet_id') or DEFAULT_SPREADSHEET_ID
    if not SPREADSHEET_ID:
        print("[FETCH] ERROR: No spreadsheet ID available")
        return None
    
    print(f"[FETCH] Spreadsheet ID: {SPREADSHEET_ID}")
    
    try:
        gc = gspread.authorize(creds)
        spreadsheet = gc.open_by_key(SPREADSHEET_ID)
        
        # Resolve source sheet by name first; avoid fixed index that breaks when new tabs are added.
        worksheet = None
        sheet_candidates = spreadsheet.worksheets()

        for sheet in sheet_candidates:
            title = str(sheet.title or '').strip().lower()
            if title in ('base', 'dados', 'database'):
                worksheet = sheet
                break

        if worksheet is None:
            # Fallback to previous behavior only if index exists
            if len(sheet_candidates) > 1:
                worksheet = sheet_candidates[1]
            elif sheet_candidates:
                worksheet = sheet_candidates[0]
            else:
                print("[FETCH] ERROR: Spreadsheet has no worksheets")
                return None

        print(f"[DATA] Reading from sheet: {worksheet.title}")
        
        # Get all data
        all_values = worksheet.get_all_values()
        headers = all_values[0]
        data_rows = all_values[1:]
        
        # Create DataFrame
        df = pd.DataFrame(data_rows, columns=headers)
        
        print(f"[DATA] Loaded {len(df)} rows")
        print(f"[DATA] Columns: {df.columns.tolist()}")
        
        # CRITICAL FILTER: Only include "Funerária" in Tipo de Cliente (Column A)
        tipo_cliente_col = None
        for col in df.columns:
            if 'tipo' in col.lower() and 'cliente' in col.lower():
                tipo_cliente_col = col
                break
        
        if tipo_cliente_col:
            print(f"[DATA] Found 'Tipo de Cliente' column: '{tipo_cliente_col}'")
            print(f"[DATA] Before filter: {len(df)} rows")
            print(f"[DATA] Unique values in Tipo de Cliente: {df[tipo_cliente_col].unique()[:10]}")
            
            # Filter to only "Funerária"
            df = df[df[tipo_cliente_col].astype(str).str.strip().str.lower() == 'funerária'].copy()
            
            print(f"[DATA] After 'Funerária' filter: {len(df)} rows")
        else:
            print(f"[DATA] WARNING: 'Tipo de Cliente' column not found. Using all data.")
        
        print(f"[DATA] ALL column names with 'fatura': {[col for col in df.columns if 'fatura' in col.lower()]}")
        
        # Find and parse Faturaçao column using ONLY PANDAS
        fat_col = None
        for col in df.columns:
            if 'fatura' in col.lower():
                fat_col = col
                break
        
        if fat_col:
            print(f"\n[DATA] Found Faturaçao column: '{fat_col}'")
            print(f"[DATA] First 10 RAW values: {df[fat_col].head(10).tolist()}")
            
            # Show samples from the MIDDLE and END of the data
            mid_point = len(df) // 2
            print(f"[DATA] Middle 10 RAW values (row {mid_point}): {df[fat_col].iloc[mid_point:mid_point+10].tolist()}")
            print(f"[DATA] Last 10 RAW values: {df[fat_col].tail(10).tolist()}")
            
            # Robust parse for European currency strings
            def parse_euro(value):
                if value is None:
                    return None
                s = str(value).strip()
                if s == "":
                    return None
                s = s.replace("\u00A0", " ")  # normalize NBSP
                # Keep digits, separators, and minus sign only
                s = re.sub(r"[^0-9,\.\-]", "", s)
                if s in {"", "-"}:
                    return None

                last_comma = s.rfind(",")
                last_dot = s.rfind(".")
                if last_comma != -1 and last_dot != -1:
                    # Both present: last separator is decimal
                    if last_comma > last_dot:
                        s = s.replace(".", "")
                        s = s.replace(",", ".")
                    else:
                        s = s.replace(",", "")
                elif last_comma != -1:
                    # Only comma present
                    parts = s.split(",")
                    if len(parts) == 2 and len(parts[1]) == 2:
                        s = s.replace(",", ".")
                    else:
                        s = s.replace(",", "")
                elif last_dot != -1:
                    # Only dot present
                    parts = s.split(".")
                    if len(parts) == 2 and len(parts[1]) == 2:
                        pass
                    else:
                        s = s.replace(".", "")

                try:
                    return float(s)
                except:
                    return None

            parsed_values = df[fat_col].apply(parse_euro)

            # Diagnostics: show parsed samples and failures
            print(f"[DATA] First 20 PARSED values: {parsed_values.head(20).tolist()}")
            failure_mask = parsed_values.isna() & df[fat_col].astype(str).str.strip().ne("")
            if failure_mask.any():
                failed_samples = df.loc[failure_mask, fat_col].head(20).tolist()
                print(f"[DATA] Example FAILED raw values: {failed_samples}")

            df[fat_col] = parsed_values
            
            total = df[fat_col].sum()
            null_count = df[fat_col].isna().sum()
            non_null_count = len(df) - null_count
            
            print(f"[DATA] Total Faturação: €{total:,.2f}")
            print(f"[DATA] Null values: {null_count}")
            print(f"[DATA] Non-null values: {non_null_count}")
        
        # Parse Quantidade
        quant_col = None
        for col in df.columns:
            if 'quant' in col.lower():
                quant_col = col
                break
        
        if quant_col:
            df[quant_col] = pd.to_numeric(df[quant_col], errors='coerce')
        
        return df
        
    except Exception as e:
        print(f"[ERROR] Failed to fetch data: {e}")
        import traceback
        traceback.print_exc()
        return None

def fetch_data():
    """Cached wrapper for fetch_data_uncached"""
    cache_key = get_cache_key('sales_data')
    cached = get_cached_data(cache_key)
    if cached is not None:
        return cached
    
    data = fetch_data_uncached()
    if data is not None:
        set_cached_data(cache_key, data)
    return data

# ============================================================================
# OBJECTIVES MANAGEMENT (Sales Targets)
# ============================================================================

def fetch_objectives_uncached():
    """Fetch objectives from 'Objetivos' sheet."""
    print("\n[OBJECTIVES] Fetching objectives...")
    try:
        creds = get_google_credentials()
        if not creds:
            print("[OBJECTIVES] No credentials")
            return None
        
        SPREADSHEET_ID = session.get('spreadsheet_id') or DEFAULT_SPREADSHEET_ID
        gc = gspread.authorize(creds)
        spreadsheet = gc.open_by_key(SPREADSHEET_ID)
        
        # Find the "Objetivos" sheet
        worksheet = None
        for sheet in spreadsheet.worksheets():
            if sheet.title.lower() == 'objetivos':
                worksheet = sheet
                break
        
        if not worksheet:
            print("[OBJECTIVES] 'Objetivos' sheet not found")
            return None
        
        all_values = worksheet.get_all_values()
        if len(all_values) < 2:
            print("[OBJECTIVES] Empty Objetivos sheet")
            return None
        
        headers = all_values[0]
        data_rows = all_values[1:]
        
        df = pd.DataFrame(data_rows, columns=headers)
        print(f"[OBJECTIVES] ✅ Loaded {len(df)} objectives")
        print(f"[OBJECTIVES] Column names in sheet: {list(df.columns)}")
        print(f"[OBJECTIVES] Full DataFrame:")
        print(df.to_string())
        
        # Debug: show what's in each column
        for col in df.columns:
            print(f"[OBJECTIVES]   {col}: {df[col].tolist()}")
        
        return df
    except Exception as e:
        print(f"[OBJECTIVES] ❌ Error: {e}")
        import traceback
        traceback.print_exc()
        return None

def fetch_objectives():
    """Cached wrapper for fetch_objectives_uncached"""
    cache_key = get_cache_key('objectives')
    cached = get_cached_data(cache_key)
    if cached is not None:
        return cached
    
    data = fetch_objectives_uncached()
    if data is not None:
        set_cached_data(cache_key, data)
    return data

def calculate_performance(comercial_name, period_type='annual', period_value=None):
    """
    Calculate performance vs objectives for a comercial.
    
    Args:
        comercial_name: Name of the comercial (e.g., "Jose Amor")
        period_type: 'annual', 'quarterly', 'monthly'
        period_value: Year (2025), Quarter (Q1 2025), Month (01/2025), or None for current
    
    Returns:
        {
            'comercial': str,
            'period': str,
            'total_revenue_target': float,
            'total_revenue_actual': float,
            'revenue_achievement_pct': float,
            'total_urnas_target': float,
            'total_urnas_actual': float,
            'urnas_achievement_pct': float,
            'by_client': [
                {
                    'client': str,
                    'revenue_target': float,
                    'revenue_actual': float,
                    'revenue_pct': float,
                    'urnas_target': float,
                    'urnas_actual': float,
                    'urnas_pct': float
                }
            ]
        }
    """
    df_sales = fetch_data()
    df_objectives = fetch_objectives()
    
    if df_sales is None or df_objectives is None:
        return None
    
    # Find columns
    def find_col(*keywords):
        for col in df_sales.columns:
            name = col.lower()
            if all(k in name for k in keywords):
                return col
        return None
    
    comercial_col = find_col('comercial')
    cliente_col = find_col('cliente')
    fat_col = find_col('fatura')
    quant_col = find_col('quant')
    zona_col = find_col('zona')
    familia_col = find_col('familia') or find_col('família')
    mes_col = find_col('mês') or find_col('mes')
    
    # Filter by scope
    if comercial_name == 'TOTAL':
        comercial_data = df_sales.copy()
    elif comercial_name == 'EXPORTAÇÃO':
        if zona_col:
            comercial_data = df_sales[df_sales[zona_col].astype(str).str.lower().str.contains('export', na=False)].copy()
        else:
            comercial_data = df_sales.iloc[0:0].copy()
    else:
        comercial_data = df_sales[df_sales[comercial_col] == comercial_name].copy()
    
    if comercial_data.empty:
        return None
    
    # Parse year/month for period filtering and target calc
    if mes_col:
        def parse_period(value):
            """
            Parse period from month column - supports multiple formats:
            - YYYY/MM, YYYY-MM, YYYY.MM
            - MM/YYYY, MM-YYYY, MM.YYYY
            Returns: (year, month) tuple or (None, None) on failure
            """
            if value is None or pd.isna(value):
                return (None, None)
            s = str(value).strip()
            if not s or s.lower() in ['nan', 'none', 'null', '']:
                return (None, None)
            
            # Normalize separators
            s = s.replace('-', '/').replace('.', '/')
            
            # Try YYYY/MM format first
            m = re.search(r"(\d{4})\D?(\d{1,2})", s)
            if m:
                year = m.group(1)
                month = m.group(2).zfill(2)
                # Validate month is 1-12
                if 1 <= int(month) <= 12:
                    return (year, month)
            
            # Try MM/YYYY format
            m = re.search(r"(\d{1,2})\D?(\d{4})", s)
            if m:
                month = m.group(1).zfill(2)
                year = m.group(2)
                # Validate month is 1-12
                if 1 <= int(month) <= 12:
                    return (year, month)
            
            # If we get here, parsing failed
            print(f"[PARSE WARNING] Could not parse period: '{value}'")
            return (None, None)
        
        ym = comercial_data[mes_col].apply(parse_period)
        comercial_data['__year'] = ym.apply(lambda x: x[0])
        comercial_data['__month'] = ym.apply(lambda x: x[1])
        
        # Log any unparsed dates for debugging
        unparsed = comercial_data[comercial_data['__year'].isna()]
        if not unparsed.empty and mes_col in unparsed.columns:
            unique_unparsed = unparsed[mes_col].unique()
            if len(unique_unparsed) > 0:
                print(f"[PARSE WARNING] {len(unparsed)} rows with unparsed dates. Samples: {list(unique_unparsed[:3])}")
    
    
    # Filter objectives by comercial/scope
    if df_objectives is not None and not df_objectives.empty and 'Comercial' in df_objectives.columns:
        obj_data = df_objectives[df_objectives['Comercial'] == comercial_name].copy()
    else:
        obj_data = pd.DataFrame()
    
    # Ensure numeric columns
    if fat_col:
        comercial_data[fat_col] = pd.to_numeric(comercial_data[fat_col], errors='coerce')
    if quant_col:
        comercial_data[quant_col] = pd.to_numeric(comercial_data[quant_col], errors='coerce')
    
    # Calculate for both previous year (for baseline) and current year (for progress)
    prev_year = None
    current_year = str(datetime.now().year)
    
    # Get previous year data (for baseline comparison)
    prev_year_data = comercial_data.copy()
    if '__year' in comercial_data.columns:
        years = sorted([y for y in comercial_data['__year'].dropna().unique() if str(y).isdigit()])
        if years:
            preferred_prev = str(int(current_year) - 1)
            if preferred_prev in years:
                prev_year = preferred_prev
            else:
                years_before_current = [y for y in years if int(y) < int(current_year)]
                prev_year = years_before_current[-1] if years_before_current else years[-1]
            prev_year_data = comercial_data[comercial_data['__year'] == prev_year]
        else:
            # No valid years parsed - log warning
            print(f"[CALC WARNING] No valid years found in data for {comercial_name}")
            prev_year_data = pd.DataFrame()
    
    # Get current year data (for current progress)
    current_year_data = comercial_data[comercial_data['__year'] == current_year] if '__year' in comercial_data.columns else pd.DataFrame()
    
    # Log data availability for debugging
    if current_year_data.empty:
        print(f"[CALC INFO] No data for current year {current_year} yet for {comercial_name}")
    if prev_year_data.empty:
        print(f"[CALC INFO] No previous year data available for {comercial_name}")
    
    # Calculate previous year totals (baseline) with safe defaults
    prev_revenue = prev_year_data[fat_col].sum() if fat_col and not prev_year_data.empty else 0
    prev_urnas_data = filter_urnas_family_rows(prev_year_data.copy(), familia_col) if not prev_year_data.empty else pd.DataFrame()
    prev_urnas_qty = prev_urnas_data[quant_col].sum() if quant_col and not prev_urnas_data.empty else 0
    
    # Calculate current year totals (current progress) with safe defaults
    current_revenue = current_year_data[fat_col].sum() if fat_col and not current_year_data.empty else 0
    current_urnas_data = filter_urnas_family_rows(current_year_data.copy(), familia_col) if not current_year_data.empty else pd.DataFrame()
    current_urnas_qty = current_urnas_data[quant_col].sum() if quant_col and not current_year_data.empty else 0
    
    # Get objectives for this period (simple approach: use first matching period)
    total_revenue_target = 0
    total_urnas_target = 0
    
    if not obj_data.empty and 'Cliente' in obj_data.columns:
        # Find row with 'Total' client or matching period
        total_obj = obj_data[obj_data['Cliente'] == 'Total']
        if not total_obj.empty:
            # Handle European locale (comma as decimal separator)
            rev_str = str(total_obj.iloc[0].get('Target_Valor', 0) or 0).strip()
            urnas_str = str(total_obj.iloc[0].get('Target_Urnas', 0) or 0).strip()
            
            # Replace comma with period for float conversion
            rev_str = rev_str.replace(',', '.')
            urnas_str = urnas_str.replace(',', '.')
            
            try:
                total_revenue_target = float(rev_str)
            except (ValueError, TypeError):
                total_revenue_target = 0
            
            try:
                total_urnas_target = float(urnas_str)
            except (ValueError, TypeError):
                total_urnas_target = 0
    
    # Calculate achievement percentages (current year vs target)
    revenue_achievement_pct = (current_revenue / total_revenue_target * 100) if total_revenue_target > 0 else 0
    urnas_achievement_pct = (current_urnas_qty / total_urnas_target * 100) if total_urnas_target > 0 else 0
    
    # Calculate how much % growth needed to reach target from current position
    revenue_to_target_pct = ((total_revenue_target - current_revenue) / current_revenue * 100) if current_revenue > 0 else 0
    urnas_to_target_pct = ((total_urnas_target - current_urnas_qty) / current_urnas_qty * 100) if current_urnas_qty > 0 else 0
    
    # Calculate historical data for previous 3 years (for trend chart)
    historical_data = []
    if mes_col and mes_col in df_sales.columns:
        # Apply same scope filter using existing data (avoid refetch)
        if comercial_name == 'TOTAL':
            scope_data = df_sales.copy()
        elif comercial_name == 'EXPORTAÇÃO':
            if zona_col:
                scope_data = df_sales[df_sales[zona_col].astype(str).str.lower().str.contains('export', na=False)].copy()
            else:
                scope_data = df_sales.iloc[0:0].copy()
        else:
            scope_data = df_sales[df_sales[comercial_col] == comercial_name].copy()

        ym = scope_data[mes_col].apply(parse_period)
        scope_data['__year'] = ym.apply(lambda x: x[0])

        # Ensure numeric
        if fat_col:
            scope_data[fat_col] = pd.to_numeric(scope_data[fat_col], errors='coerce')
        if quant_col:
            scope_data[quant_col] = pd.to_numeric(scope_data[quant_col], errors='coerce')

        # Get last 3 years available (>= 2022)
        all_years = sorted([y for y in scope_data['__year'].dropna().unique() if str(y).isdigit() and int(y) >= 2022])
        last_3_years = all_years[-3:] if len(all_years) >= 3 else all_years

        prev_revenue = None
        prev_avg_total = None
        prev_avg_urnas = None
        
        for year in sorted(last_3_years):
            year_data = scope_data[scope_data['__year'] == year]
            year_revenue = year_data[fat_col].sum() if fat_col else 0
            year_clients = year_data[cliente_col].nunique() if cliente_col else 0

            # URNAS for this year
            year_urnas = filter_urnas_family_rows(year_data.copy(), familia_col)
            year_urnas_rev = year_urnas[fat_col].sum() if fat_col else 0
            year_urnas_qty = year_urnas[quant_col].sum() if quant_col else 0
            
            # Calculate averages
            avg_per_urna_total = (year_revenue / year_urnas_qty) if year_urnas_qty else 0
            avg_per_urna_urnas = (year_urnas_rev / year_urnas_qty) if year_urnas_qty else 0
            
            # Revenue growth
            if prev_revenue is None:
                growth_text = "—"
                growth_pct = None
            else:
                diff = year_revenue - prev_revenue
                growth_pct = (diff / prev_revenue * 100) if prev_revenue else 0
                growth_text = f"€{diff:,.2f} ({growth_pct:+.1f}%)"
            
            # Avg Total growth
            if prev_avg_total is None or prev_avg_total == 0:
                growth_avg_total_text = "—"
                growth_avg_total_pct = None
            else:
                growth_avg_total_pct = ((avg_per_urna_total - prev_avg_total) / prev_avg_total * 100)
                growth_avg_total_text = f"{growth_avg_total_pct:+.1f}%"
            
            # Avg URNAS growth
            if prev_avg_urnas is None or prev_avg_urnas == 0:
                growth_avg_urnas_text = "—"
                growth_avg_urnas_pct = None
            else:
                growth_avg_urnas_pct = ((avg_per_urna_urnas - prev_avg_urnas) / prev_avg_urnas * 100)
                growth_avg_urnas_text = f"{growth_avg_urnas_pct:+.1f}%"

            historical_data.append({
                'year': year,
                'revenue': round(year_revenue, 2),
                'urnas': round(year_urnas_qty, 0),
                'clients': year_clients,
                'avg_per_urna_total': round(avg_per_urna_total, 2),
                'avg_per_urna_urnas': round(avg_per_urna_urnas, 2),
                'growth_text': growth_text,
                'growth_pct': growth_pct,
                'growth_avg_total_text': growth_avg_total_text,
                'growth_avg_total_pct': growth_avg_total_pct,
                'growth_avg_urnas_text': growth_avg_urnas_text,
                'growth_avg_urnas_pct': growth_avg_urnas_pct
            })
            
            prev_revenue = year_revenue
            prev_avg_total = avg_per_urna_total
            prev_avg_urnas = avg_per_urna_urnas
    
    # Client-level objectives disabled (sales force only)
    by_client = []
    
    commission_rate = COMMISSION_RATES.get(comercial_name, 0)
    commission_value = current_revenue * commission_rate if current_revenue else 0

    return {
        'comercial': comercial_name,
        'period': period_value or 'Annual',
        'total_revenue_target': round(total_revenue_target, 2),
        'total_revenue_prev_year': round(prev_revenue, 2),  # Previous year (baseline)
        'total_revenue_current': round(current_revenue, 2),  # Current year (progress)
        'revenue_achievement_pct': round(revenue_achievement_pct, 1),  # Current vs target
        'revenue_to_target_pct': round(revenue_to_target_pct, 1),  # % growth needed
        'total_urnas_target': round(total_urnas_target, 0),
        'total_urnas_prev_year': round(prev_urnas_qty, 0),  # Previous year (baseline)
        'total_urnas_current': round(current_urnas_qty, 0),  # Current year (progress)
        'urnas_achievement_pct': round(urnas_achievement_pct, 1),  # Current vs target
        'urnas_to_target_pct': round(urnas_to_target_pct, 1),  # % growth needed
        'commission_rate': commission_rate,
        'commission_value': round(commission_value, 2),
        'historical_data': historical_data,
        'by_client': by_client
    }

# ============================================================================
# VISIT REPORTS FUNCTIONS
# ============================================================================

def fetch_visit_reports_uncached(client_name=None):
    """Fetch visit reports from 'Visit Reports' sheet."""
    print("\n[VISIT_REPORTS] Fetching visit reports...")
    try:
        creds = get_google_credentials()
        if not creds:
            print("[VISIT_REPORTS] No credentials")
            return None
        
        SPREADSHEET_ID = session.get('spreadsheet_id') or DEFAULT_SPREADSHEET_ID
        gc = gspread.authorize(creds)
        spreadsheet = gc.open_by_key(SPREADSHEET_ID)
        
        # Find the "Visit Reports" sheet
        worksheet = None
        for sheet in spreadsheet.worksheets():
            if sheet.title.lower() == 'visit reports':
                worksheet = sheet
                break
        
        if not worksheet:
            print("[VISIT_REPORTS] 'Visit Reports' sheet not found - will create on first save")
            return pd.DataFrame()
        
        all_values = worksheet.get_all_values()
        if len(all_values) < 2:
            print("[VISIT_REPORTS] Empty Visit Reports sheet")
            return pd.DataFrame()
        
        headers = all_values[0]
        data_rows = all_values[1:]
        
        df = pd.DataFrame(data_rows, columns=headers)
        print(f"[VISIT_REPORTS] Loaded {len(df)} visit reports")
        
        # Filter by client if specified
        if client_name:
            df = df[df.get('Cliente', '').astype(str).str.strip() == client_name]
            print(f"[VISIT_REPORTS] Filtered to {len(df)} reports for client: {client_name}")
        
        return df
    except Exception as e:
        print(f"[VISIT_REPORTS] Error: {e}")
        return pd.DataFrame()

def fetch_visit_reports(client_name=None):
    """Cached wrapper for fetch_visit_reports_uncached"""
    cache_key = get_cache_key(f'visit_reports:{client_name}' if client_name else 'visit_reports')
    cached = get_cached_data(cache_key)
    if cached is not None:
        return cached
    
    data = fetch_visit_reports_uncached(client_name)
    if not data.empty:
        set_cached_data(cache_key, data)
    return data


def fetch_contacts_uncached():
    """Fetch contacts/prospects from contacto_clientes/Contacts/Contactos sheet."""
    print("\n[CONTACTS] Fetching contacts...")
    try:
        creds = get_google_credentials()
        if not creds:
            print("[CONTACTS] No credentials")
            return pd.DataFrame()

        spreadsheet_id = session.get('spreadsheet_id') or DEFAULT_SPREADSHEET_ID
        gc = gspread.authorize(creds)
        spreadsheet = gc.open_by_key(spreadsheet_id)

        worksheet = None
        for sheet in spreadsheet.worksheets():
            title = sheet.title.strip().lower()
            if title in ('contacto_clientes', 'contacts', 'contactos'):
                worksheet = sheet
                break

        if not worksheet:
            print("[CONTACTS] Contacts sheet not found")
            return pd.DataFrame()

        all_values = worksheet.get_all_values()
        if len(all_values) < 2:
            return pd.DataFrame()

        headers = all_values[0]
        rows = all_values[1:]
        df = pd.DataFrame(rows, columns=headers)

        # Drop rows that are completely empty
        if not df.empty:
            non_empty_mask = df.apply(lambda r: any(str(v).strip() for v in r.values), axis=1)
            df = df[non_empty_mask].copy()

        print(f"[CONTACTS] Loaded {len(df)} contacts")
        return df
    except Exception as e:
        print(f"[CONTACTS] Error: {e}")
        return pd.DataFrame()


def fetch_contacts():
    """Cached wrapper for contacts."""
    cache_key = get_cache_key('contacts')
    cached = get_cached_data(cache_key)
    if cached is not None:
        return cached

    data = fetch_contacts_uncached()
    if not data.empty:
        set_cached_data(cache_key, data)
    return data


def save_contact(contact_data):
    """Save a contact/prospect row in contacto_clientes/Contacts/Contactos sheet."""
    print("\n[CONTACTS] Saving contact...")
    try:
        creds = get_google_credentials()
        if not creds:
            return False, "Credenciais não disponíveis"

        spreadsheet_id = session.get('spreadsheet_id') or DEFAULT_SPREADSHEET_ID
        gc = gspread.authorize(creds)
        spreadsheet = gc.open_by_key(spreadsheet_id)

        worksheet = None
        for sheet in spreadsheet.worksheets():
            title = sheet.title.strip().lower()
            if title in ('contacto_clientes', 'contacts', 'contactos'):
                worksheet = sheet
                break

        default_headers = [
            'Cliente',
            'Nome Fiscal',
            'Morada',
            'Telefone',
            'N.º Contribuinte',
            'Email',
            'Comercial',
            'Tipo',
            'Data Criação',
        ]

        if not worksheet:
            worksheet = spreadsheet.add_worksheet("contacto_clientes", rows=2000, cols=20)
            worksheet.insert_row(default_headers, 1)

        headers = worksheet.row_values(1)
        if not headers:
            headers = default_headers
            worksheet.insert_row(headers, 1)

        created_at = datetime.now().strftime("%d/%m/%Y %H:%M")
        header_map = {
            'cliente': contact_data.get('cliente', ''),
            'nome fiscal': contact_data.get('nome_fiscal', ''),
            'morada': contact_data.get('morada', ''),
            'telefone': contact_data.get('telefone', ''),
            'n.º contribuinte': contact_data.get('nif', ''),
            'nif': contact_data.get('nif', ''),
            'email': contact_data.get('email', ''),
            'comercial': contact_data.get('comercial', ''),
            'tipo': contact_data.get('tipo', 'Prospecto'),
            'data criação': created_at,
        }

        row = []
        for header in headers:
            key = str(header).strip().lower()
            row.append(header_map.get(key, ''))

        worksheet.append_row(row)

        clear_cache('contacts')
        return True, "Contacto guardado com sucesso"
    except Exception as e:
        print(f"[CONTACTS] Save error: {e}")
        return False, f"Erro ao guardar contacto: {str(e)}"

def get_comercial_email_from_name(comercial_name):
    """Returns the first email for a comercial (for single email lookups)"""
    if not comercial_name:
        return None

    normalized_name = str(comercial_name).strip().lower()

    if '@' in normalized_name:
        return normalize_email(normalized_name)

    for email, comercial_names in SALES_ACCESS_MAP.items():
        for mapped_name in comercial_names:
            if str(mapped_name).strip().lower() == normalized_name:
                return normalize_email(email)

    return None

def get_all_emails_for_comercial(comercial_name):
    """Returns ALL emails for a comercial (for notifications)"""
    if not comercial_name:
        return []

    normalized_name = str(comercial_name).strip().lower()
    
    if '@' in normalized_name:
        return [normalize_email(normalized_name)]
    
    emails = []
    for email, comercial_names in SALES_ACCESS_MAP.items():
        for mapped_name in comercial_names:
            if str(mapped_name).strip().lower() == normalized_name:
                emails.append(normalize_email(email))
    
    return emails

def get_visit_report_notification_recipients(comercial_name=None):
    recipients = set()

    recipients.update([normalize_email(email) for email in ADMIN_EMAILS if email])

    # Get ALL emails for this comercial (supports multiple emails per comercial)
    comercial_emails = get_all_emails_for_comercial(comercial_name)
    recipients.update(comercial_emails)
    
    # Return first comercial email for backward compatibility
    primary_email = comercial_emails[0] if comercial_emails else None

    return sorted([email for email in recipients if email]), primary_email

def send_visit_followup_notification(client_name, comercial_name, visit_date, followup_date,
                                     summary, next_actions, status):
    if not followup_date:
        return True, ""

    if not SMTP_ENABLED:
        return False, "SMTP desativado (defina SMTP_ENABLED=true para enviar emails)"

    if not SMTP_USERNAME or not SMTP_PASSWORD:
        return False, "SMTP não configurado (defina SMTP_USERNAME e SMTP_PASSWORD)"

    recipients, comercial_email = get_visit_report_notification_recipients(comercial_name)
    if not recipients:
        return False, "Sem destinatários configurados para notificações"

    warning_msg = ""
    if not comercial_email:
        warning_msg = "Aviso: comercial sem email mapeado; notificação enviada apenas para admins"

    subject = f"[VISITA] Follow-up agendado para {client_name} ({followup_date})"
    body = (
        "Foi registado um relatório de visita com data de seguimento.\n\n"
        f"Cliente: {client_name}\n"
        f"Comercial: {comercial_name}\n"
        f"Data da visita: {visit_date}\n"
        f"Data de seguimento: {followup_date}\n"
        f"Estado: {status}\n"
        f"Resumo: {summary or 'N/A'}\n"
        f"Próximas ações: {next_actions or 'N/A'}\n"
    )

    try:
        message = MIMEMultipart()
        message['From'] = SMTP_USERNAME
        message['To'] = ', '.join(recipients)
        message['Subject'] = subject
        message.attach(MIMEText(body, 'plain', 'utf-8'))

        with smtplib.SMTP(SMTP_SERVER, SMTP_PORT, timeout=15) as server:
            server.starttls()
            server.login(SMTP_USERNAME, SMTP_PASSWORD)
            server.sendmail(SMTP_USERNAME, recipients, message.as_string())

        return True, warning_msg
    except Exception as e:
        return False, str(e)

def save_visit_report(client_name, comercial_name, visit_date, visit_type, summary, 
                      next_actions, status, followup_date=None, budget=None, products=None):
    """Save a new visit report to Google Sheets"""
    print("\n[VISIT_REPORTS] Saving new visit report...")
    try:
        creds = get_google_credentials()
        if not creds:
            print("[VISIT_REPORTS] No credentials")
            return False, "Credenciais não disponíveis"
        
        SPREADSHEET_ID = session.get('spreadsheet_id') or DEFAULT_SPREADSHEET_ID
        gc = gspread.authorize(creds)
        spreadsheet = gc.open_by_key(SPREADSHEET_ID)
        
        # Find or create "Visit Reports" sheet
        worksheet = None
        for sheet in spreadsheet.worksheets():
            if sheet.title.lower() == 'visit reports':
                worksheet = sheet
                break
        
        if not worksheet:
            # Create the sheet
            worksheet = spreadsheet.add_worksheet("Visit Reports", rows=1000, cols=11)
            headers = ["Data Visita", "Comercial", "Cliente", "Tipo Visita", 
                      "Resumo", "Próximas Ações", "Estado", "Data Seguimento", 
                      "Orçamento", "Produtos", "Data Criação"]
            worksheet.insert_row(headers, 1)
            print("[VISIT_REPORTS] Created new 'Visit Reports' sheet")
        
        # Prepare row data
        import datetime as dt
        creation_date = dt.datetime.now().strftime("%d/%m/%Y %H:%M")
        row_data = [
            visit_date,
            comercial_name,
            client_name,
            visit_type,
            summary,
            next_actions,
            status,
            followup_date or '',
            budget or '',
            products or '',
            creation_date
        ]
        
        # Append row
        worksheet.append_row(row_data)
        print(f"[VISIT_REPORTS] Saved visit report for {client_name}")
        
        # Clear visit reports cache
        clear_cache(f'visit_reports:{client_name}')
        clear_cache('visit_reports')

        notification_msg = ""
        notification_sent, notification_error = send_visit_followup_notification(
            client_name=client_name,
            comercial_name=comercial_name,
            visit_date=visit_date,
            followup_date=followup_date,
            summary=summary,
            next_actions=next_actions,
            status=status
        )

        if followup_date:
            if notification_sent:
                notification_msg = " (email de seguimento enviado)"
                if notification_error:
                    notification_msg += f" — {notification_error}"
                print(f"[VISIT_REPORTS] Follow-up notification sent for {client_name}")
            else:
                notification_msg = " (relatório guardado, mas falha no envio de email)"
                print(f"[VISIT_REPORTS] Follow-up notification failed: {notification_error}")
        
        return True, f"Relatório de visita guardado com sucesso{notification_msg}"
    except Exception as e:
        print(f"[VISIT_REPORTS] Error saving: {e}")
        return False, f"Erro ao guardar relatório de visita: {str(e)}"

# ============================================================================
# ROUTES
# ============================================================================

@app.route('/')
def index():
    if current_user.is_authenticated:
        # Route users to their appropriate dashboard
        user_email = normalize_email(session.get('user_email'))
        user_role = get_user_role(user_email)
        
        # Warehouse team goes to inventory
        if user_role == 'warehouse':
            return redirect(url_for('inventory'))
        # Everyone else goes to sales dashboard
        else:
            return redirect(url_for('dashboard'))
    return redirect(url_for('login'))

@app.route('/login')
def login():
    print("[LOGIN] Starting login flow...")
    # Ensure stale OAuth state/tokens do not poison a fresh login attempt.
    session.pop('state', None)
    session.pop('oauth_code_verifier', None)
    flow = get_flow()
    authorization_url, state = flow.authorization_url(
        access_type='offline',
        prompt='consent'
    )
    print(f"[LOGIN] Authorization URL: {authorization_url[:80]}...")
    session['state'] = state
    # Persist PKCE verifier to complete token exchange in callback.
    if getattr(flow, 'code_verifier', None):
        session['oauth_code_verifier'] = flow.code_verifier
    return redirect(authorization_url)

@app.route('/dev-login')
def dev_login():
    """Development-only fallback login for LAN demos without public HTTPS OAuth callback."""
    if IS_PRODUCTION:
        return "Not available in production", 404

    email = normalize_email(request.args.get('email'))
    if not email:
        allowed = sorted(set(list(ADMIN_EMAILS) + list(COMMERCIAL_EMAILS) + list(WAREHOUSE_EMAILS) + list(USERS_ROLES.keys())))
        links = "".join([f'<li><a href="/dev-login?email={e}">{e}</a></li>' for e in allowed])
        return (
            "<h2>Dev Login (Development Only)</h2>"
            "<p>Select an email to enter without Google OAuth.</p>"
            f"<ul>{links}</ul>"
        )

    role = get_user_role(email)
    if not role:
        return f"Email not allowed: {email}", 403

    session['user_email'] = email
    session['user_name'] = email.split('@')[0]
    session['user_role'] = role
    session.permanent = True

    user_id = f"dev-{email}"
    user = User(user_id, email=email, role=role)
    users[user_id] = user
    login_user(user, remember=True)

    if role == 'warehouse':
        return redirect(url_for('inventory'))
    return redirect(url_for('dashboard'))

@app.route('/oauth2callback')
def oauth2callback():
    print("\n[AUTH] OAuth2 callback received")
    state_in_session = session.get('state')
    state_in_request = request.args.get('state')

    if state_in_session and state_in_request and state_in_session != state_in_request:
        print(f"[AUTH] State mismatch: session={state_in_session} request={state_in_request}")
        session.pop('state', None)
        session.pop('oauth_code_verifier', None)
        return redirect(url_for('login'))

    flow = get_flow(state=state_in_session)
    code_verifier = session.get('oauth_code_verifier')
    if code_verifier:
        flow.code_verifier = code_verifier

    try:
        flow.fetch_token(authorization_response=request.url)
    except Exception as e:
        # Typical causes: reused/expired auth code, redirect_uri mismatch, stale callback.
        print(f"[AUTH] Token exchange failed: {type(e).__name__}: {e}")
        session.pop('state', None)
        session.pop('oauth_code_verifier', None)
        session.pop('credentials', None)
        return redirect(url_for('login'))

    session.pop('state', None)
    session.pop('oauth_code_verifier', None)
    
    credentials = flow.credentials
    print(f"[AUTH] Got credentials: {credentials.token[:20]}...")
    
    session['credentials'] = {
        'token': credentials.token,
        'refresh_token': credentials.refresh_token,
        'token_uri': credentials.token_uri,
        'client_id': credentials.client_id,
        'client_secret': credentials.client_secret,
        'scopes': credentials.scopes
    }
    session.permanent = True
    print(f"[AUTH] Saved credentials to session")
    
    # Get user info
    import requests
    user_info = requests.get(
        'https://www.googleapis.com/oauth2/v1/userinfo',
        headers={'Authorization': f'Bearer {credentials.token}'}
    ).json()

    user_email = normalize_email(user_info.get('email'))
    session['user_email'] = user_email
    session['user_name'] = user_info.get('name') or user_info.get('given_name')
    
    # Assign role based on email
    user_role = get_user_role(user_email)
    session['user_role'] = user_role
    
    # Initialize test user view (defaults to Jose Amor)
    if is_test_view_switch_user(user_email) and 'test_user_view' not in session:
        session['test_user_view'] = 'José Amor'
        print(f"[TEST_USER] Initialized view to José Amor")
    
    user_id = user_info['id']
    user = User(user_id, email=user_email, role=user_role)
    users[user_id] = user
    login_user(user, remember=True)
    
    print(f"[AUTH] User logged in: {user_id} ({user_email}) with role '{user_role}'")
    
    # Redirect based on role
    if user_role == 'warehouse':
        print(f"[AUTH] Redirecting warehouse user to inventory")
        return redirect(url_for('inventory'))
    else:
        print(f"[AUTH] Redirecting {user_role} user to dashboard")
        return redirect(url_for('dashboard'))

@app.route('/logout')
@login_required
def logout():
    logout_user()
    session.clear()
    return redirect(url_for('login'))

# ============================================================================
# TEST USER VIEW SWITCHER (for demonstrations)
# ============================================================================

def is_test_view_switch_user(user_email=None):
    """Return True when current request belongs to the demo switch user."""
    def local_part(value):
        value = normalize_email(value)
        if not value:
            return ''
        return value.split('@')[0].strip().lower().replace('.', '')

    email = normalize_email(user_email)
    if not email:
        email = normalize_email(session.get('user_email'))
    if not email and hasattr(current_user, 'email'):
        email = normalize_email(getattr(current_user, 'email', None))

    email_local = local_part(email)
    return (
        email in {'tiagovibecoding@gmail.com', 'tiago.vibecoding@gmail.com'}
        or email_local in {'tiagovibecoding', 'tiagorebelo'}
        or email_local.startswith('tiagovibecoding')
    )

def can_use_demo_view_switcher(user_email=None, user_role=None):
    """
    Demo switcher access policy:
    - Only for configured test user.
    """
    return is_test_view_switch_user(user_email)

def get_user_comercials(user_email):
    """
    Get the list of comercials that a user can view.
    For test user (tiagovibecoding@gmail.com), respects the session view selection.
    """
    user_role = get_user_role(user_email)

    # In demo mode, selected view (if present) overrides comercial access.
    if can_use_demo_view_switcher(user_email, user_role) and session.get('test_user_view'):
        # Get the selected view from session (default to José Amor)
        selected_view = session.get('test_user_view', 'José Amor')
        return [selected_view]
    
    # For all other users, return their normal access
    return SALES_ACCESS_MAP.get(user_email, [])

@app.route('/switch-test-view', methods=['POST'])
@login_required
def switch_test_view():
    """
    Allow test user to switch between José Amor and Hélder Oliveira views.
    Only accessible by tiagovibecoding@gmail.com
    """
    if not can_use_demo_view_switcher(getattr(current_user, 'email', None), getattr(current_user, 'role', None)):
        return jsonify({'success': False, 'error': 'Unauthorized'}), 403
    
    data = request.get_json()
    view = data.get('view', 'José Amor')
    
    # Validate view selection
    if view not in ['José Amor', 'Hélder Oliveira']:
        return jsonify({'success': False, 'error': 'Invalid view'}), 400
    
    # Store in session
    session['test_user_view'] = view
    
    print(f"[TEST_USER] View switched to: {view}")
    
    return jsonify({
        'success': True,
        'view': view,
        'message': f'Vista alterada para {view}'
    })

@app.route('/save-visit-report', methods=['POST'])
@login_required
def save_visit_report_route():
    """Handle visit report submission"""
    print("\n[VISIT_REPORTS] Received visit report submission")
    
    try:
        data = request.get_json()
        
        # Extract data
        client_name = data.get('cliente', '').strip()
        comercial_name = data.get('comercial', '').strip()
        visit_date = data.get('visit_date', '').strip()
        visit_type = data.get('visit_type', '').strip()
        summary = data.get('summary', '').strip()
        next_actions = data.get('next_actions', '').strip()
        status = data.get('status', 'Pendente').strip()
        followup_date = data.get('followup_date', '').strip() or None
        budget = data.get('budget', '').strip() or None
        products = data.get('products', '').strip() or None
        
        # Validate required fields
        if not all([client_name, comercial_name, visit_date]):
            return jsonify({'success': False, 'error': 'Cliente, Comercial e Data da Visita são obrigatórios'}), 400
        
        # Save to Google Sheets
        success, message = save_visit_report(
            client_name=client_name,
            comercial_name=comercial_name,
            visit_date=visit_date,
            visit_type=visit_type,
            summary=summary,
            next_actions=next_actions,
            status=status,
            followup_date=followup_date,
            budget=budget,
            products=products
        )
        
        if success:
            return jsonify({'success': True, 'message': message})
        else:
            return jsonify({'success': False, 'error': message}), 500
    
    except Exception as e:
        print(f"[VISIT_REPORTS] Error in route: {e}")
        return jsonify({'success': False, 'error': str(e)}), 500


@app.route('/save-contact', methods=['POST'])
@login_required
def save_contact_route():
    """Save a contact/prospect from app UI."""
    try:
        user_email = normalize_email(session.get('user_email'))
        user_role = get_user_role(user_email)
        if user_role not in ('admin', 'comercial'):
            return jsonify({'success': False, 'error': 'Sem permissão para criar contactos'}), 403

        data = request.get_json() or {}
        cliente = str(data.get('cliente', '')).strip()
        comercial = str(data.get('comercial', '')).strip()

        if not cliente:
            return jsonify({'success': False, 'error': 'Nome do cliente é obrigatório'}), 400

        # Enforce comercial ownership for comercial users
        if user_role == 'comercial':
            allowed = get_user_comercials(user_email)
            if allowed and comercial and comercial not in allowed:
                return jsonify({'success': False, 'error': 'Comercial inválido para o seu perfil'}), 400
            if allowed and not comercial:
                comercial = allowed[0]

        payload = {
            'cliente': cliente,
            'nome_fiscal': str(data.get('nome_fiscal', '')).strip(),
            'morada': str(data.get('morada', '')).strip(),
            'telefone': str(data.get('telefone', '')).strip(),
            'nif': str(data.get('nif', '')).strip(),
            'email': str(data.get('email', '')).strip(),
            'comercial': comercial,
            'tipo': str(data.get('tipo', 'Prospecto')).strip() or 'Prospecto',
        }

        success, message = save_contact(payload)
        if success:
            return jsonify({'success': True, 'message': message})
        return jsonify({'success': False, 'error': message}), 500
    except Exception as e:
        return jsonify({'success': False, 'error': str(e)}), 500


@app.route('/contacts')
@login_required
def contacts():
    """Contacts/Prospects management with quick visit report registration."""
    user_email = normalize_email(session.get('user_email'))
    user_role = get_user_role(user_email)

    if not has_dashboard_access(user_role, user_email):
        return redirect(url_for('dashboard'))

    restricted_user = user_role == 'comercial'
    assigned_comerciais = get_user_comercials(user_email) if restricted_user else []

    contacts_df = fetch_contacts()
    contacts_records = []
    if contacts_df is not None and not contacts_df.empty:
        df = contacts_df.copy()

        # Restrict contacts by comercial for comercial users (when column exists)
        comercial_col = None
        for col in df.columns:
            if 'comercial' in str(col).lower():
                comercial_col = col
                break

        if restricted_user and comercial_col and assigned_comerciais:
            allowed = [c.strip().lower() for c in assigned_comerciais]
            df = df[df[comercial_col].astype(str).str.strip().str.lower().isin(allowed)]

        df = df.fillna('')
        contacts_records = df.to_dict('records')

    # Build a normalized list of existing clients from sales data for matching
    sales_client_lookup = set()
    sales_client_values = []
    try:
        sales_df = fetch_data()
        if sales_df is not None and not sales_df.empty:
            sales_scope = sales_df.copy()

            # Restrict sales users to their own comercials only
            if restricted_user and assigned_comerciais:
                comercial_col = None
                for col in sales_scope.columns:
                    if 'comercial' in str(col).lower():
                        comercial_col = col
                        break
                if comercial_col:
                    allowed = [c.strip().lower() for c in assigned_comerciais]
                    sales_scope = sales_scope[sales_scope[comercial_col].astype(str).str.strip().str.lower().isin(allowed)]

            cliente_col = None
            for col in sales_scope.columns:
                if 'cliente' in str(col).lower():
                    cliente_col = col
                    break

            if cliente_col:
                def _norm_name(value):
                    return re.sub(r'\s+', ' ', str(value or '').strip().lower())

                for value in sales_scope[cliente_col].dropna().tolist():
                    name = str(value).strip()
                    if not name:
                        continue
                    sales_client_lookup.add(_norm_name(name))
                    sales_client_values.append(name)
    except Exception as e:
        print(f"[CONTACTS] Could not load sales client matching: {e}")

    # Comercial options for forms
    if restricted_user and assigned_comerciais:
        comercial_options = assigned_comerciais
    else:
        all_names = []
        for names in SALES_ACCESS_MAP.values():
            all_names.extend(names)
        comercial_options = sorted(list(set(all_names))) if all_names else []

    contacts_rows = ''
    if contacts_records:
        def _norm_name(value):
            return re.sub(r'\s+', ' ', str(value or '').strip().lower())

        for row in contacts_records[:500]:
            cliente = row.get('Cliente', row.get('cliente', ''))
            nome_fiscal = row.get('Nome Fiscal', row.get('nome fiscal', ''))
            morada = row.get('Morada', row.get('morada', ''))
            telefone = row.get('Telefone', row.get('telefone', ''))
            nif = row.get('N.º Contribuinte', row.get('NIF', row.get('nif', '')))
            email = row.get('Email', row.get('email', ''))
            comercial = row.get('Comercial', row.get('comercial', ''))
            tipo = row.get('Tipo', row.get('tipo', ''))
            match_status = 'Cliente ativo' if _norm_name(cliente) in sales_client_lookup else 'Prospecto'
            row_comercial = str(comercial or '').strip().lower().replace('"', '&quot;')
            contacts_rows += f"<tr data-status=\"{match_status}\" data-comercial=\"{row_comercial}\"><td>{cliente}</td><td>{nome_fiscal}</td><td>{morada}</td><td>{telefone}</td><td>{nif}</td><td>{email}</td><td>{comercial}</td><td>{tipo}</td><td>{match_status}</td></tr>"
    else:
        contacts_rows = "<tr><td colspan='9' style='color:#999;'>Sem contactos registados</td></tr>"

    all_client_values = sorted(list(set(sales_client_values + [str((r.get('Cliente') or r.get('cliente') or '')).strip() for r in contacts_records])))

    client_options = ''.join([
        f"<option value=\"{str((r.get('Cliente') or r.get('cliente') or '')).replace(chr(34), '&quot;')}\"></option>"
        for r in contacts_records if (r.get('Cliente') or r.get('cliente'))
    ])
    client_options += ''.join([
        f"<option value=\"{name.replace(chr(34), '&quot;')}\"></option>"
        for name in all_client_values if name
    ])

    comercial_select_options = ''.join([
        f"<option value=\"{c}\">{c}</option>" for c in comercial_options
    ])
    comercial_filter_options = ''.join([
        f"<option value=\"{c.strip().lower().replace(chr(34), '&quot;')}\">{c}</option>" for c in comercial_options
    ])

    can_edit = user_role in ('admin', 'comercial')

    html = f"""
    <!DOCTYPE html>
    <html>
    <head>
        <title>Contactos e Prospeccao</title>
        <meta charset="UTF-8">
        <style>
            body {{ font-family: 'Segoe UI', Tahoma, sans-serif; padding: 20px; background: #f5f7fa; color: #333; }}
            .container {{ max-width: 1400px; margin: 0 auto; }}
            .card {{ background: white; padding: 18px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); margin-bottom: 16px; }}
            .nav-tabs {{ display: flex; gap: 10px; margin-bottom: 15px; }}
            .nav-tabs a {{ text-decoration: none; padding: 10px 14px; border-radius: 6px; background: #eef2f8; color: #3d4d66; font-weight: 600; }}
            .nav-tabs a.active {{ background: #dbe7ff; color: #1f3f7a; }}
            .grid2 {{ display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }}
            label {{ display:block; font-size: 13px; margin-bottom: 4px; color:#555; }}
            input, select, textarea {{ width: 100%; padding: 9px; border: 1px solid #d4dbe5; border-radius: 6px; }}
            button {{ padding: 10px 14px; border: none; border-radius: 6px; cursor: pointer; font-weight: 600; }}
            .btn-primary {{ background: #4064d7; color: white; }}
            .btn-success {{ background: #16a34a; color: white; }}
            table {{ width: 100%; border-collapse: collapse; font-size: 13px; }}
            th, td {{ border: 1px solid #e6ebf2; padding: 8px; text-align: left; }}
            th {{ background: #f6f9fd; }}
            .msg {{ margin-top: 8px; padding: 8px; border-radius: 6px; display: none; }}
            .muted {{ color:#7a869a; font-size:12px; }}
            .table-toolbar {{ display:flex; justify-content:space-between; align-items:center; gap:10px; margin-bottom:10px; flex-wrap:wrap; }}
            .table-toolbar select {{ max-width: 280px; }}
            @media (max-width: 900px) {{ .grid2 {{ grid-template-columns: 1fr; }} }}
        </style>
    </head>
    <body>
        <div class="container">
            <div class="nav-tabs">
                <a href="/dashboard">📊 Vendas</a>
                <a href="/contacts" class="active">📇 Contactos</a>
                {'<a href="/inventory">📦 Inventário</a>' if user_role in ['admin', 'warehouse'] else ''}
                <a href="/logout">🚪 Sair</a>
            </div>

            <div class="card">
                <h2 style="margin-top:0;">📇 Contactos e Prospeccao</h2>
                <p class="muted">Use esta lista para guardar potenciais clientes e registar visitas mesmo sem vendas no histórico.</p>
            </div>

            <div class="grid2">
                <div class="card">
                    <h3 style="margin-top:0;">➕ Novo Contacto / Prospecto</h3>
                    {'' if can_edit else '<p class="muted">Perfil de visualização: sem permissões para editar.</p>'}
                    <form id="contactForm" style="display:grid; gap:10px;">
                        <div><label>Cliente *</label><input id="c_cliente" required {'' if can_edit else 'disabled'}></div>
                        <div><label>Nome Fiscal</label><input id="c_nome_fiscal" {'' if can_edit else 'disabled'}></div>
                        <div><label>Morada</label><input id="c_morada" {'' if can_edit else 'disabled'}></div>
                        <div class="grid2">
                            <div><label>Telefone</label><input id="c_telefone" {'' if can_edit else 'disabled'}></div>
                            <div><label>NIF</label><input id="c_nif" {'' if can_edit else 'disabled'}></div>
                        </div>
                        <div><label>Email</label><input id="c_email" type="email" {'' if can_edit else 'disabled'}></div>
                        <div class="grid2">
                            <div><label>Comercial</label><select id="c_comercial" {'' if can_edit else 'disabled'}>{comercial_select_options}</select></div>
                            <div><label>Tipo</label><select id="c_tipo" {'' if can_edit else 'disabled'}><option value="Prospecto">Prospecto</option><option value="Cliente">Cliente</option></select></div>
                        </div>
                        <button class="btn-primary" type="submit" {'' if can_edit else 'disabled'}>Guardar Contacto</button>
                        <div id="contactMsg" class="msg"></div>
                    </form>
                </div>

                <div class="card">
                    <h3 style="margin-top:0;">📝 Registar Visita (Prospecto ou Cliente)</h3>
                    <form id="quickVisitForm" style="display:grid; gap:10px;">
                        <div><label>Cliente *</label><input id="v_cliente" list="contactClientList" required placeholder="Escolha da lista ou escreva novo nome"></div>
                        <datalist id="contactClientList">{client_options}</datalist>
                        <div class="grid2">
                            <div><label>Comercial *</label><select id="v_comercial" required>{comercial_select_options}</select></div>
                            <div><label>Data da Visita *</label><input id="v_date" type="date" required></div>
                        </div>
                        <div><label>Resumo *</label><textarea id="v_summary" rows="3" required></textarea></div>
                        <div><label>Próximas Ações *</label><textarea id="v_actions" rows="2" required></textarea></div>
                        <div class="grid2">
                            <div><label>Estado</label><select id="v_status"><option>Pendente</option><option>Concluído</option><option>Agendado</option></select></div>
                            <div><label>Tipo de Visita</label><select id="v_type"><option>Contacto Inicial</option><option>Seguimento</option><option>Negociação</option><option>Acordo</option><option>Resolução de Problema</option><option>Outro</option></select></div>
                        </div>
                        <button class="btn-success" type="submit" {'' if can_edit else 'disabled'}>Guardar Relatório de Visita</button>
                        <div id="visitMsg" class="msg"></div>
                    </form>
                </div>
            </div>

            <div class="card">
                <h3 style="margin-top:0;">📋 Lista de Contactos</h3>
                <div class="table-toolbar">
                    <div class="muted">Filtro rápido por estado</div>
                    <div style="display:flex; gap:8px; flex-wrap:wrap;">
                        <select id="contactStatusFilter">
                            <option value="all">Estado: Todos</option>
                            <option value="Prospecto">Estado: Prospectos</option>
                            <option value="Cliente ativo">Estado: Clientes ativos</option>
                        </select>
                        <select id="contactComercialFilter">
                            <option value="all">Comercial: Todos</option>
                            {comercial_filter_options}
                        </select>
                    </div>
                </div>
                <table>
                    <tr><th>Cliente</th><th>Nome Fiscal</th><th>Morada</th><th>Telefone</th><th>NIF</th><th>Email</th><th>Comercial</th><th>Tipo</th><th>Estado</th></tr>
                    {contacts_rows}
                </table>
            </div>
        </div>

        <script>
        const today = new Date().toISOString().slice(0,10);
        const dateInput = document.getElementById('v_date');
        if (dateInput && !dateInput.value) dateInput.value = today;

        function showMsg(el, ok, text) {{
            el.style.display = 'block';
            el.style.background = ok ? '#e8f7ec' : '#fde8e8';
            el.style.color = ok ? '#166534' : '#b91c1c';
            el.textContent = text;
        }}

        const contactForm = document.getElementById('contactForm');
        if (contactForm) {{
            contactForm.addEventListener('submit', async (e) => {{
                e.preventDefault();
                const msg = document.getElementById('contactMsg');
                try {{
                    const payload = {{
                        cliente: document.getElementById('c_cliente').value,
                        nome_fiscal: document.getElementById('c_nome_fiscal').value,
                        morada: document.getElementById('c_morada').value,
                        telefone: document.getElementById('c_telefone').value,
                        nif: document.getElementById('c_nif').value,
                        email: document.getElementById('c_email').value,
                        comercial: document.getElementById('c_comercial').value,
                        tipo: document.getElementById('c_tipo').value,
                    }};
                    const resp = await fetch('/save-contact', {{
                        method: 'POST',
                        headers: {{'Content-Type':'application/json'}},
                        body: JSON.stringify(payload)
                    }});
                    const data = await resp.json();
                    if (data.success) {{
                        showMsg(msg, true, '✓ ' + data.message);
                        contactForm.reset();
                        setTimeout(() => location.reload(), 900);
                    }} else {{
                        showMsg(msg, false, '✗ ' + (data.error || 'Erro ao guardar contacto'));
                    }}
                }} catch (err) {{
                    showMsg(msg, false, '✗ ' + err.message);
                }}
            }});
        }}

        const quickVisitForm = document.getElementById('quickVisitForm');
        if (quickVisitForm) {{
            quickVisitForm.addEventListener('submit', async (e) => {{
                e.preventDefault();
                const msg = document.getElementById('visitMsg');
                try {{
                    const payload = {{
                        cliente: document.getElementById('v_cliente').value,
                        comercial: document.getElementById('v_comercial').value,
                        visit_date: document.getElementById('v_date').value,
                        visit_type: document.getElementById('v_type').value,
                        summary: document.getElementById('v_summary').value,
                        next_actions: document.getElementById('v_actions').value,
                        status: document.getElementById('v_status').value,
                        followup_date: '',
                        budget: '',
                        products: ''
                    }};
                    const resp = await fetch('/save-visit-report', {{
                        method: 'POST',
                        headers: {{'Content-Type':'application/json'}},
                        body: JSON.stringify(payload)
                    }});
                    const data = await resp.json();
                    if (data.success) {{
                        showMsg(msg, true, '✓ ' + data.message);
                        quickVisitForm.reset();
                        const dateInput2 = document.getElementById('v_date');
                        if (dateInput2) dateInput2.value = today;
                    }} else {{
                        showMsg(msg, false, '✗ ' + (data.error || 'Erro ao guardar visita'));
                    }}
                }} catch (err) {{
                    showMsg(msg, false, '✗ ' + err.message);
                }}
            }});
        }}

        const contactStatusFilter = document.getElementById('contactStatusFilter');
        const contactComercialFilter = document.getElementById('contactComercialFilter');

        function applyContactFilters() {{
            const selectedStatus = contactStatusFilter ? contactStatusFilter.value : 'all';
            const selectedComercial = contactComercialFilter ? contactComercialFilter.value : 'all';
            const rows = document.querySelectorAll('table tr[data-status]');

            rows.forEach((row) => {{
                const rowStatus = row.getAttribute('data-status') || '';
                const rowComercial = row.getAttribute('data-comercial') || '';
                const statusOk = selectedStatus === 'all' || rowStatus === selectedStatus;
                const comercialOk = selectedComercial === 'all' || rowComercial === selectedComercial;
                row.style.display = (statusOk && comercialOk) ? '' : 'none';
            }});
        }}

        if (contactStatusFilter) contactStatusFilter.addEventListener('change', applyContactFilters);
        if (contactComercialFilter) contactComercialFilter.addEventListener('change', applyContactFilters);
        </script>
    </body>
    </html>
    """
    return html

@app.route('/test-data')
@login_required
def test_data():
    """Debug endpoint to test data loading."""
    print("\n" + "="*80)
    print("[TEST] Testing data load...")
    print("="*80)
    
    df = fetch_data()
    
    if df is None:
        print("[TEST] fetch_data() returned None")
        return jsonify({'error': 'fetch_data returned None', 'session_id': session.get('spreadsheet_id')}), 400
    
    print("[TEST] fetch_data() succeeded!")
    
    # Find columns
    fat_col = None
    quant_col = None
    for col in df.columns:
        if 'fatura' in col.lower() and not fat_col:
            fat_col = col
        if 'quant' in col.lower() and not quant_col:
            quant_col = col
    
    # Get totals
    total_fat_all = df[fat_col].sum() if fat_col else 0
    
    mes_col = None
    for col in df.columns:
        if 'mês' in col.lower() or 'mes' in col.lower():
            mes_col = col
            break
    
    # Use dynamic year - get previous full year
    previous_year = str(datetime.now().year - 1)
    total_fat_previous = 0
    
    if mes_col and fat_col:
        total_fat_previous = df[df[mes_col].str.contains(previous_year, na=False)][fat_col].sum()
    
    result = {
        'total_rows': len(df),
        'total_faturacao_all': float(total_fat_all),
        f'total_faturacao_{previous_year}': float(total_fat_previous),
        'previous_year': previous_year,
        'columns_found': {
            'faturaçao': fat_col,
            'quantidade': quant_col,
            'mes': mes_col
        }
    }
    
    print(f"[TEST] Result: {result}")
    
    return jsonify(result)

@app.route('/raw-data')
@login_required
def raw_data():
    """Show completely raw data - no parsing, no filtering."""
    print("\n" + "="*80)
    print("[RAW] Loading COMPLETELY RAW data from sheet...")
    print("="*80)
    
    creds = get_google_credentials()
    if not creds:
        return jsonify({'error': 'No credentials'}), 401
    
    SPREADSHEET_ID = session.get('spreadsheet_id')
    if not SPREADSHEET_ID:
        return jsonify({'error': 'No spreadsheet ID'}), 400
    
    try:
        gc = gspread.authorize(creds)
        spreadsheet = gc.open_by_key(SPREADSHEET_ID)
        
        # Get sheet BASE (index 1)
        worksheet = spreadsheet.worksheets()[1]
        print(f"[RAW] Sheet name: {worksheet.title}")
        print(f"[RAW] Sheet size: {worksheet.row_count} rows x {worksheet.col_count} cols")
        
        # Get ALL values
        all_values = worksheet.get_all_values()
        print(f"[RAW] get_all_values() returned {len(all_values)} rows")
        
        headers = all_values[0]
        print(f"\n[RAW] Column headers ({len(headers)} cols):")
        for i, h in enumerate(headers):
            print(f"[RAW]   [{i}] '{h}'")
        
        # Find Faturaçao column
        fat_col_idx = None
        fat_col_name = None
        for i, h in enumerate(headers):
            if 'fatura' in h.lower():
                fat_col_idx = i
                fat_col_name = h
                break
        
        if fat_col_idx is None:
            print("[RAW] ERROR: Faturaçao column NOT FOUND!")
            return jsonify({'error': 'Faturaçao column not found', 'columns': headers}), 400
        
        print(f"\n[RAW] Found Faturaçao at column [{fat_col_idx}]: '{fat_col_name}'")
        
        # Get all data rows (skip header)
        data_rows = all_values[1:]
        print(f"[RAW] Total data rows: {len(data_rows)}")
        
        # Create DataFrame WITHOUT any parsing
        df = pd.DataFrame(data_rows, columns=headers)
        print(f"[RAW] DataFrame shape: {df.shape}")
        
        # Show raw Faturaçao values
        print(f"\n[RAW] First 20 RAW Faturaçao values (NO PARSING):")
        for i, val in enumerate(df[fat_col_name].head(20)):
            print(f"[RAW]   [{i}] {repr(val)} (type: {type(val).__name__})")
        
        # Try to convert to numeric (pandas auto-convert)
        print(f"\n[RAW] Attempting pandas numeric conversion...")
        fat_numeric = pd.to_numeric(df[fat_col_name], errors='coerce')
        
        print(f"[RAW] Converted values:")
        print(f"[RAW]   Non-null count: {fat_numeric.notna().sum()}")
        print(f"[RAW]   Null/NaN count: {fat_numeric.isna().sum()}")
        print(f"[RAW]   Sum: {fat_numeric.sum():,.2f}")
        print(f"[RAW]   First 20 converted values: {fat_numeric.head(20).tolist()}")
        
        # Show sample of problematic values
        print(f"\n[RAW] Sample of values that couldn't be converted:")
        problem_vals = df[fat_col_name][fat_numeric.isna()].head(10)
        for i, val in enumerate(problem_vals):
            print(f"[RAW]   {repr(val)}")
        
        result = {
            'total_rows': len(data_rows),
            'total_columns': len(headers),
            'column_names': headers,
            'faturaçao_column': fat_col_name,
            'faturaçao_column_index': fat_col_idx,
            'raw_faturaçao_samples': df[fat_col_name].head(20).tolist(),
            'numeric_sum': float(fat_numeric.sum()),
            'converted_non_null': int(fat_numeric.notna().sum()),
            'converted_null': int(fat_numeric.isna().sum()),
            'expected_from_looker_studio': 34467590.51
        }
        
        print(f"\n[RAW] RESULT: {result}")
        
        return jsonify(result)
        
    except Exception as e:
        print(f"[RAW] ERROR: {e}")
        import traceback
        traceback.print_exc()
        return jsonify({'error': str(e)}), 500

@app.route('/dashboard')
@login_required
def dashboard():
    """Minimal dashboard - just show the data."""
    print("\n[DASHBOARD] Loading dashboard...")
    
    # Check role-based access
    user_email = normalize_email(session.get('user_email'))
    user_role = get_user_role(user_email)
    
    if not has_dashboard_access(user_role, user_email):
        # Warehouse staff cannot access sales dashboard
        return f"""
        <!DOCTYPE html>
        <html>
        <head>
            <title>Acesso Negado</title>
            <style>
                body {{ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #f5f7fa 0%, #eef2f5 100%); margin: 0; padding: 40px; }}
                .container {{ max-width: 500px; margin: 60px auto; background: white; padding: 40px; border-radius: 8px; box-shadow: 0 4px 16px rgba(100, 140, 200, 0.1); text-align: center; }}
                h1 {{ color: #d32f2f; margin-top: 0; }}
                p {{ color: #666; line-height: 1.6; margin: 20px 0; }}
                .info-box {{ background: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; margin: 20px 0; border-radius: 4px; text-align: left; }}
                .button {{ display: inline-block; padding: 12px 24px; background: #667eea; color: white; text-decoration: none; border-radius: 4px; margin-top: 20px; cursor: pointer; }}
                .button:hover {{ background: #5568d3; }}
            </style>
        </head>
        <body>
            <div class="container">
                <h1>🚫 Acesso Negado</h1>
                <p>Desculpe, você não tem permissão para acessar o Módulo de Vendas.</p>
                <div class="info-box">
                    <strong>ℹ️ Seu Perfil:</strong><br>
                    Função: <strong>{user_role.upper()}</strong><br><br>
                    Este módulo é para a equipa de vendas (Comercial, Visualizadores e Administradores).<br><br>
                    Se você é membro da equipa de armazém, aceda ao módulo de Inventário em vez disso.
                </div>
                <a href="/inventory" class="button">→ Ir para Inventário</a>
                <a href="/logout" class="button">🚪 Sair</a>
            </div>
        </body>
        </html>
        """, 403
    
    # Check if we need to re-login
    creds = get_google_credentials()
    if not creds:
        print("[DASHBOARD] Credentials invalid, need to re-login")
        html = f"""
        <!DOCTYPE html>
        <html>
        <head><title>Dashboard - Novo Login Necessário</title></head>
        <body style="font-family: Arial; padding: 40px; text-align: center;">
            <h1>Sessão Expirada</h1>
            <p>As suas credenciais Google expiraram. Faça login novamente.</p>
            <a href="/login" style="padding: 10px 20px; background: #667eea; color: white; text-decoration: none; border-radius: 4px; display: inline-block;">
                Entrar novamente com Google
            </a>
        </body>
        </html>
        """
        return html
    
    df = fetch_data()
    
    if df is None:
        html = """
        <!DOCTYPE html>
        <html>
        <head><title>Dashboard</title></head>
        <body style="font-family: Arial; padding: 40px;">
            <h1>Configurar Spreadsheet</h1>
            <p>O seu ID da Spreadsheet: <strong>1ayEGU0h_R7CY55COC1U94-p0rJch109YBGvezjYjHWw</strong></p>
            <input type="text" id="sid" placeholder="ID da Spreadsheet" style="width: 400px; padding: 10px;" 
                   value="1ayEGU0h_R7CY55COC1U94-p0rJch109YBGvezjYjHWw">
            <button onclick="connectSheet()" 
                    style="padding: 10px 20px; background: #667eea; color: white; border: none; cursor: pointer;">
                Conectar
            </button>
            <p id="status"></p>
            <script>
            function connectSheet() {
                const sid = document.getElementById('sid').value;
                document.getElementById('status').textContent = 'A ligar...';
                fetch('/set-spreadsheet?id=' + encodeURIComponent(sid))
                    .then(r => r.json())
                    .then(data => {
                        if (data.success) {
                            document.getElementById('status').textContent = 'Ligado! A recarregar...';
                            setTimeout(() => location.reload(), 500);
                        } else {
                            document.getElementById('status').textContent = 'Erro na ligação';
                        }
                    })
                    .catch(e => {
                        document.getElementById('status').textContent = 'Erro: ' + e;
                    });
            }
            </script>
        </body>
        </html>
        """
        return html
    
    def find_col(*keywords):
        for col in df.columns:
            name = col.lower()
            if all(k in name for k in keywords):
                return col
        return None

    fat_col = find_col('fatura')
    quant_col = find_col('quant')
    cliente_col = find_col('cliente')
    zona_col = find_col('zona')
    comercial_col = find_col('comercial')
    familia_col = find_col('familia') or find_col('família')
    mes_col = find_col('mês') or find_col('mes')

    # Build year/month columns from mes_col
    if mes_col:
        def parse_period(value):
            if value is None:
                return (None, None)
            s = str(value).strip()
            if not s:
                return (None, None)
            s = s.replace('-', '/').replace('.', '/')
            m = re.search(r"(\d{4})\D?(\d{1,2})", s)
            if m:
                year = m.group(1)
                month = m.group(2).zfill(2)
                return (year, month)
            m = re.search(r"(\d{1,2})\D?(\d{4})", s)
            if m:
                month = m.group(1).zfill(2)
                year = m.group(2)
                return (year, month)
            return (None, None)

        ym = df[mes_col].apply(parse_period)
        df['__year'] = ym.apply(lambda x: x[0])
        df['__month'] = ym.apply(lambda x: x[1])
    else:
        df['__year'] = None
        df['__month'] = None

    # Apply access control based on user role
    assigned_comerciais = []
    user_email = session.get('user_email')
    user_name = session.get('user_name')
    user_role = get_user_role(user_email) if user_email else None
    restricted_user = user_role == 'comercial'
    
    # For comercial users: only show their own data
    if restricted_user:
        assigned_comerciais = get_user_comercials(user_email)

    # Last 3 years summary (access-limited, not filter-limited)
    df_access = df.copy()
    if restricted_user:
        if comercial_col and assigned_comerciais:
            allowed = [a.strip().lower() for a in assigned_comerciais]
            df_access = df_access[
                df_access[comercial_col].astype(str).str.strip().str.lower().isin(allowed)
            ]
        else:
            # Safety: never fall back to company-wide data for comercial users.
            df_access = df_access.iloc[0:0]

    df_access_num = df_access.copy()
    if fat_col:
        df_access_num[fat_col] = pd.to_numeric(df_access_num[fat_col], errors='coerce')
    if quant_col:
        df_access_num[quant_col] = pd.to_numeric(df_access_num[quant_col], errors='coerce')

    last3_rows_html = "<tr><td colspan='8'>No data</td></tr>"
    if '__year' in df_access_num.columns and fat_col:
        all_years = sorted([y for y in df_access_num['__year'].dropna().unique() if str(y).isdigit() and int(y) >= 2022])
        last_3_years = all_years[-3:]
        rows = []
        prev_revenue = None
        prev_avg_total = None
        prev_avg_urnas = None
        for year in last_3_years:
            year_data = df_access_num[df_access_num['__year'] == year]
            year_revenue = year_data[fat_col].sum() if fat_col else 0
            year_clients = year_data[cliente_col].nunique() if cliente_col else 0
            year_urnas_rev = 0
            year_urnas_qty = 0
            year_urnas = filter_urnas_family_rows(year_data.copy(), familia_col)
            if fat_col:
                year_urnas_rev = year_urnas[fat_col].sum()
            if quant_col:
                year_urnas_qty = year_urnas[quant_col].sum()
            avg_per_urna_total = (year_revenue / year_urnas_qty) if year_urnas_qty else 0
            avg_per_urna_urnas = (year_urnas_rev / year_urnas_qty) if year_urnas_qty else 0
            
            # Revenue growth
            if prev_revenue is None:
                growth_text = "—"
            else:
                diff = year_revenue - prev_revenue
                pct = (diff / prev_revenue * 100) if prev_revenue else 0
                growth_text = f"€{diff:,.2f} ({pct:+.1f}%)"
            
            # Avg Total growth
            if prev_avg_total is None or prev_avg_total == 0:
                growth_avg_total = "—"
            else:
                pct_total = ((avg_per_urna_total - prev_avg_total) / prev_avg_total * 100)
                growth_avg_total = f"{pct_total:+.1f}%"
            
            # Avg URNAS growth
            if prev_avg_urnas is None or prev_avg_urnas == 0:
                growth_avg_urnas = "—"
            else:
                pct_urnas = ((avg_per_urna_urnas - prev_avg_urnas) / prev_avg_urnas * 100)
                growth_avg_urnas = f"{pct_urnas:+.1f}%"
            
            rows.append(
                f"<tr><td>{year}</td><td>€{year_revenue:,.2f}</td><td>{growth_text}</td><td>€{avg_per_urna_total:,.2f}</td><td>{growth_avg_total}</td><td>€{avg_per_urna_urnas:,.2f}</td><td>{growth_avg_urnas}</td><td>{year_clients:,}</td></tr>"
            )
            prev_revenue = year_revenue
            prev_avg_total = avg_per_urna_total
            prev_avg_urnas = avg_per_urna_urnas
        if rows:
            last3_rows_html = "".join(rows)

    # Apply filters - set current year as default
    current_year_str = str(datetime.now().year)
    year_filter = request.args.get('year', current_year_str if current_year_str in df['__year'].astype(str).values else 'all')
    month_filter = request.args.get('month', 'all')
    zona_filter = request.args.get('zona', 'all')
    comercial_filter = request.args.get('comercial', 'all')
    familia_filter = request.args.get('familia', 'all')
    cliente_filter = request.args.get('cliente', 'all')

    filter_qs = urlencode(
        {
            'year': year_filter,
            'month': month_filter,
            'zona': zona_filter,
            'comercial': comercial_filter,
            'familia': familia_filter,
        },
        quote_via=quote_plus
    )

    filtered = df.copy()
    if year_filter != 'all':
        filtered = filtered[filtered['__year'] == year_filter]
    if month_filter != 'all':
        filtered = filtered[filtered['__month'] == month_filter]
    if zona_col and zona_filter != 'all':
        filtered = filtered[filtered[zona_col] == zona_filter]
    if comercial_col and comercial_filter != 'all':
        filtered = filtered[filtered[comercial_col] == comercial_filter]
    if familia_col and familia_filter != 'all':
        filtered = filtered[filtered[familia_col] == familia_filter]
    if cliente_col and cliente_filter != 'all':
        filtered = filtered[filtered[cliente_col] == cliente_filter]

    if restricted_user:
        if comercial_col and assigned_comerciais:
            allowed = [a.strip().lower() for a in assigned_comerciais]
            filtered = filtered[
                filtered[comercial_col].astype(str).str.strip().str.lower().isin(allowed)
            ]
        else:
            # Safety: never fall back to company-wide data for comercial users.
            filtered = filtered.iloc[0:0]

    # Calculate totals
    total_fat = filtered[fat_col].sum() if fat_col else 0
    total_quant = filtered[quant_col].sum() if quant_col else 0
    total_clients = filtered[cliente_col].nunique() if cliente_col else 0
    total_rows = len(filtered)

    # Analytics
    monthly = []
    if fat_col:
        # Check if any filter is applied
        any_filter_applied = (
            year_filter != 'all' or 
            month_filter != 'all' or 
            zona_filter != 'all' or 
            comercial_filter != 'all' or 
            familia_filter != 'all' or 
            cliente_filter != 'all'
        )
        # Show max 12 months
        months_to_show = 12
        monthly = (
            filtered.dropna(subset=['__year', '__month'])
            .assign(period=lambda d: d['__year'] + '-' + d['__month'])
            .groupby('period')[fat_col]
            .sum()
            .sort_index(ascending=False)
            .head(months_to_show)
            .reset_index()
            .values.tolist()
        )

    by_zona = []
    if zona_col and fat_col:
        by_zona = (
            filtered.groupby(zona_col)[fat_col]
            .sum()
            .sort_values(ascending=False)
            .head(10)
            .reset_index()
            .values.tolist()
        )

    by_comercial = []
    if comercial_col and fat_col:
        by_comercial = (
            filtered.groupby(comercial_col)[fat_col]
            .sum()
            .sort_values(ascending=False)
            .head(10)
            .reset_index()
            .values.tolist()
        )

    by_familia = []
    if familia_col and fat_col:
        by_familia = (
            filtered.groupby(familia_col)[fat_col]
            .sum()
            .sort_values(ascending=False)
            .head(10)
            .reset_index()
            .values.tolist()
        )

    by_zona = []
    if zona_col and fat_col:
        by_zona = (
            filtered.groupby(zona_col)[fat_col]
            .sum()
            .sort_values(ascending=False)
            .reset_index()
            .values.tolist()
        )

    # Top products by quantity (URNAS ONLY)
    referencia_col = find_col('referencia')
    by_product_qty = []
    urnas_norm = None
    if referencia_col and familia_col:
        urnas_data = filter_urnas_family_rows(filtered, familia_col)

        def normalize_ref(value):
            s = str(value).strip()
            if not s:
                return s
            m = re.match(r'^[Cc]\s*(\d+)$', s)
            if m:
                return m.group(1)
            m = re.match(r'^(\d+)$', s)
            if m:
                return m.group(1)
            return s

        special_merge = {'122', '124', '126'}

        def build_ref_display(norm, refs):
            refs_clean = [str(v).strip() for v in refs if str(v).strip()]
            # For merged groups, show all unique references
            if norm == '122_124_126':
                return " / ".join(sorted(set(refs_clean)))
            # For others, show the normalized reference
            return str(norm)

        urnas_norm = urnas_data.assign(
            __ref_norm=urnas_data[referencia_col].apply(normalize_ref),
            __ref_orig=urnas_data[referencia_col].astype(str).str.strip()
        )
        urnas_norm['__ref_group'] = urnas_norm['__ref_norm'].apply(
            lambda r: '122_124_126' if str(r) in special_merge else str(r)
        )

    if urnas_norm is not None and quant_col:
        grouped_qty = (
            urnas_norm.groupby('__ref_group')
            .agg(
                __qty=(quant_col, 'sum'),
                __refs=('__ref_orig', lambda x: list({v for v in x if v}))
            )
        )
        grouped_qty['__display'] = grouped_qty.apply(
            lambda row: build_ref_display(row.name, row['__refs']), axis=1
        )
        by_product_qty = (
            grouped_qty.sort_values(by='__qty', ascending=False)
            .head(20)
            .reset_index(drop=True)
            [['__display', '__qty']]
            .values.tolist()
        )

    # Top products by revenue
    by_product_rev = []
    if urnas_norm is not None and fat_col:
        grouped_rev = (
            urnas_norm.groupby('__ref_group')
            .agg(
                __rev=(fat_col, 'sum'),
                __refs=('__ref_orig', lambda x: list({v for v in x if v}))
            )
        )
        grouped_rev['__display'] = grouped_rev.apply(
            lambda row: build_ref_display(row.name, row['__refs']), axis=1
        )
        by_product_rev = (
            grouped_rev.sort_values(by='__rev', ascending=False)
            .head(20)
            .reset_index(drop=True)
            [['__display', '__rev']]
            .values.tolist()
        )

    # Client summary (URNAS-only for quantity)
    clients_summary = []
    if cliente_col and fat_col and quant_col:
        # Filter to urnas only for quantity calculations
        urnas_filtered = filter_urnas_family_rows(filtered, familia_col) if familia_col else filtered
        
        clients_summary = (
            filtered.groupby(cliente_col)[fat_col].sum().reset_index(name=fat_col)
        )
        if not urnas_filtered.empty:
            urnas_qty = urnas_filtered.groupby(cliente_col)[quant_col].sum().reset_index(name='__urnas_qty')
            clients_summary = clients_summary.merge(urnas_qty, on=cliente_col, how='left')
            clients_summary['__urnas_qty'] = clients_summary['__urnas_qty'].fillna(0)
        else:
            clients_summary['__urnas_qty'] = 0
        
        clients_summary = (
            clients_summary
            .sort_values(by=fat_col, ascending=False)
            .values.tolist()
        )
        # Convert to tuples (cliente, faturacao, urnas_qty) for template rendering
        clients_summary = [(c, f, int(q)) for c, f, q in clients_summary]

    # Filter options
    years = sorted([y for y in df['__year'].dropna().unique().tolist() if y])
    months = sorted([m for m in df['__month'].dropna().unique().tolist() if m])
    zonas = sorted(df[zona_col].dropna().unique().tolist()) if zona_col else []
    comerciais = sorted(df[comercial_col].dropna().unique().tolist()) if comercial_col else []
    familias = sorted(df[familia_col].dropna().unique().tolist()) if familia_col else []
    clientes = sorted(df[cliente_col].dropna().unique().tolist()) if cliente_col else []

    user_role = get_user_role(user_email)
    restricted_user = user_role == 'comercial'
    
    # === PRIORITY ACTIONS GENERATION ===
    # Generate action-oriented insights for commercial agents
    # Note: Inactive clients section removed - business does not track orders
    
    all_revenue_drop_clients = pah.get_revenue_drop_clients(
        df=df_access,
        cliente_col=cliente_col,
        mes_col=mes_col,
        fat_col=fat_col,
        __year_col='__year',
        comercial_filter=assigned_comerciais if assigned_comerciais else None,
        drop_threshold=20,
        limit=None
    )

    priority_total_clients = len(all_revenue_drop_clients)
    priority_display_count = min(10, priority_total_clients)

    if priority_total_clients:
        if priority_total_clients <= 10:
            priority_count_label = f"({priority_total_clients} clientes)"
        else:
            priority_count_label = f"(10 de {priority_total_clients} clientes)"
    else:
        priority_count_label = ''
    
    # Placeholder for visit-related actions (to be implemented when visit tracking is added)
    clients_without_visits = []  # pah.get_clients_without_recent_visits(...)
    upcoming_visits = []  # pah.get_upcoming_visits(...)
    
    annual_year_options = ''.join([
        f'<option value="{y}" {"selected" if y == (year_filter if year_filter != "all" else years[-1] if years else y) else ""}>{y}</option>'
        for y in years
    ])
    annual_report_link = (
        f'''<form method="get" action="/annual-report" style="display: flex; gap: 10px; align-items: center;">
            <select name="year" style="padding: 8px; border-radius: 6px; border: 1px solid #ddd;">
                {annual_year_options}
            </select>
            <button type="submit" style="padding: 10px; background: #10b981; color: white; border-radius: 6px; text-decoration: none; text-align: center; font-weight: 600; cursor: pointer; border: none;">📊 Relatório Anual</button>
        </form>'''
        if not restricted_user else
        f'''<div style="display: flex; gap: 10px; align-items: center; flex-wrap: wrap;">
            <form method="get" action="/annual-report" style="display: flex; gap: 10px; align-items: center;">
                <input type="hidden" name="scope" value="personal">
                <select name="year" style="padding: 8px; border-radius: 6px; border: 1px solid #ddd;">
                    {annual_year_options}
                </select>
                <button type="submit" style="padding: 10px; background: #10b981; color: white; border-radius: 6px; text-decoration: none; text-align: center; font-weight: 600; cursor: pointer; border: none;">📊 Relatório Anual</button>
            </form>
            <a href="/performance" style="padding: 10px 16px; background: linear-gradient(135deg, #667eea, #764ba2); color: white; border-radius: 6px; text-decoration: none; text-align: center; font-weight: 600; font-size: 14px; white-space: nowrap; transition: all 0.3s ease;" onmouseover="this.style.transform='translateY(-2px)'; this.style.boxShadow='0 4px 12px rgba(102, 126, 234, 0.4)'" onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='none'">📈 Ver Minha Progressão & Objetivos</a>
        </div>'''
    )
    
    # Admin controls for data health monitoring  
    admin_controls_html = (
        '''<div style="background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%); border: 2px solid #cbd5e1; border-radius: 10px; padding: 20px 24px; margin: 20px 0 40px 0; box-shadow: 0 2px 8px rgba(0,0,0,0.08);">
            <div style="font-size: 13px; font-weight: 700; color: #475569; text-transform: uppercase; letter-spacing: 0.8px; margin-bottom: 16px; padding-bottom: 12px; border-bottom: 2px solid #e2e8f0;">⚙️ Admin Tools</div>
            <div style="display: flex; gap: 12px; flex-wrap: wrap;">
                <a href="/data-health" style="padding: 12px 18px; background: linear-gradient(135deg, #10b981 0%, #059669 100%); color: white; border-radius: 6px; text-decoration: none; font-weight: 600; font-size: 13px; display: inline-flex; align-items: center; gap: 6px; box-shadow: 0 2px 6px rgba(16, 185, 129, 0.25); transition: all 0.2s;" onmouseover="this.style.transform='translateY(-1px)'; this.style.boxShadow='0 4px 8px rgba(16, 185, 129, 0.3)'" onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='0 2px 6px rgba(16, 185, 129, 0.25)'">
                    🔍 Data Health Check
                </a>
                <a href="/debug/familia-values" style="padding: 12px 18px; background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); color: white; border-radius: 6px; text-decoration: none; font-weight: 600; font-size: 13px; display: inline-flex; align-items: center; gap: 6px; box-shadow: 0 2px 6px rgba(245, 158, 11, 0.25); transition: all 0.2s;" onmouseover="this.style.transform='translateY(-1px)'; this.style.boxShadow='0 4px 8px rgba(245, 158, 11, 0.3)'" onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='0 2px 6px rgba(245, 158, 11, 0.25)'">
                    🔍 Debug Familia
                </a>
                <a href="/clear-cache" style="padding: 12px 18px; background: linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%); color: white; border-radius: 6px; text-decoration: none; font-weight: 600; font-size: 13px; display: inline-flex; align-items: center; gap: 6px; box-shadow: 0 2px 6px rgba(139, 92, 246, 0.25); transition: all 0.2s;" onmouseover="this.style.transform='translateY(-1px)'; this.style.boxShadow='0 4px 8px rgba(139, 92, 246, 0.3)'" onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='0 2px 6px rgba(139, 92, 246, 0.25)'">
                    🗑️ Clear Cache
                </a>
                <a href="/salesforce-objectives-planner" style="padding: 12px 18px; background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%); color: white; border-radius: 6px; text-decoration: none; font-weight: 600; font-size: 13px; display: inline-flex; align-items: center; gap: 6px; box-shadow: 0 2px 6px rgba(37, 99, 235, 0.25); transition: all 0.2s;" onmouseover="this.style.transform='translateY(-1px)'; this.style.boxShadow='0 4px 8px rgba(37, 99, 235, 0.3)'" onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='0 2px 6px rgba(37, 99, 235, 0.25)'">
                    🎯 Planeador Objetivos
                </a>
            </div>
        </div>'''
        if user_role == 'admin' else ''
    )
    
    if 'test_user_view' not in session:
        session['test_user_view'] = 'José Amor'

    # Show demo switcher only for the dedicated test profile.
    show_test_view_switcher = can_use_demo_view_switcher(user_email, user_role)

    html = f"""
    <!DOCTYPE html>
    <html>
    <head>
        <title>Dashboard de Vendas</title>
        <meta charset="UTF-8">
        <style>
            @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');
            
            * {{ margin: 0; padding: 0; box-sizing: border-box; }}
            html {{ scroll-behavior: smooth; }}
            body {{ 
                font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; 
                padding: 0;
                margin: 0;
                background: linear-gradient(135deg, #f5f7fa 0%, #eef2f5 100%);
                min-height: 100vh;
                color: #3d4557;
            }}

            :root {{
                --dashboard-max-width: 1760px;
                --dashboard-width: min(96vw, var(--dashboard-max-width));
            }}
            
            .container {{
                width: var(--dashboard-width);
                max-width: var(--dashboard-max-width);
                margin: 0 auto;
                padding: 26px 24px 34px;
            }}
            
            @media (max-width: 1920px) {{
                .container {{ width: var(--dashboard-width); max-width: var(--dashboard-max-width); }}
            }}
            
            @media (max-width: 1600px) {{
                .container {{ width: min(96vw, 1420px); max-width: 1420px; }}
            }}
            
            @media (max-width: 1366px) {{
                .container {{ width: min(96vw, 1220px); max-width: 1220px; }}
            }}
            
            @media (max-width: 1024px) {{
                .container {{ max-width: 960px; padding: 30px; }}
            }}
            
            @media (max-width: 768px) {{
                .container {{ max-width: 100%; padding: 20px; }}
            }}
            
            .header-bar {{
                background: linear-gradient(135deg, #ffffff 0%, #f9fbfd 100%);
                padding: 18px 40px;
                display: flex;
                align-items: center;
                justify-content: space-between;
                border-bottom: 1px solid rgba(100, 140, 200, 0.12);
                box-shadow: 0 2px 12px rgba(100, 140, 200, 0.08);
            }}
            
            .header-bar img {{
                height: 40px;
                object-fit: contain;
                opacity: 0.95;
            }}
            
            .user-section {{
                display: flex;
                align-items: center;
                gap: 20px;
            }}
            
            .user-info {{
                font-size: 13px;
                color: #6b7684;
                font-weight: 500;
            }}
            
            .logout-btn {{
                padding: 8px 16px;
                background: rgba(100, 140, 200, 0.08);
                color: #4a5f8f;
                border: 1px solid rgba(100, 140, 200, 0.15);
                border-radius: 6px;
                font-size: 13px;
                font-weight: 600;
                cursor: pointer;
                transition: all 0.3s ease;
            }}
            
            .logout-btn:hover {{
                background: rgba(100, 140, 200, 0.12);
                border-color: rgba(100, 140, 200, 0.25);
                color: #3a4f7f;
            }}
            
            /* Responsive table wrapper */
            .table-wrapper {{
                overflow-x: auto;
                width: 100%;
            }}
            
            h1 {{
                color: #2d3a4d;
                font-weight: 700;
                font-size: 28px;
                margin-bottom: 32px;
                letter-spacing: -0.5px;
            }}
            
            .card {{ 
                background: linear-gradient(135deg, rgba(255, 255, 255, 0.8) 0%, rgba(249, 251, 253, 0.8) 100%);
                padding: 28px 32px; 
                margin: 0; 
                border-radius: 10px; 
                border: 1px solid rgba(100, 140, 200, 0.12);
                backdrop-filter: blur(5px);
                box-shadow: 0 4px 16px rgba(100, 140, 200, 0.06);
                transition: all 0.3s ease;
                width: 100%;
                box-sizing: border-box;
             }}
            
            @media (max-width: 768px) {{
                .card {{ padding: 20px; }}
            }}
            
            .card:hover {{ 
                border-color: rgba(100, 140, 200, 0.2);
                box-shadow: 0 8px 24px rgba(100, 140, 200, 0.12); 
                transform: translateY(-2px);
            }}
            
            .section-title {{
                font-size: 14px;
                font-weight: 700;
                color: #2d3a4d;
                margin-bottom: 24px;
                text-transform: uppercase;
                letter-spacing: 1px;
                border-bottom: 2px solid rgba(100, 140, 200, 0.25);
                padding-bottom: 12px;
                display: inline-block;
            }}
            
            .filters {{ display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin: 24px 0; }}
            @media (max-width: 1024px) {{ .filters {{ grid-template-columns: repeat(2, 1fr); }} }}
            @media (max-width: 768px) {{ .filters {{ grid-template-columns: 1fr; }} }}
            
            .filters select {{ 
                padding: 12px 14px; 
                border-radius: 8px; 
                border: 1px solid rgba(100, 140, 200, 0.2); 
                font-family: 'Inter', sans-serif;
                font-size: 14px;
                font-weight: 500;
                color: #3d4557;
                background: rgba(255, 255, 255, 0.6);
                transition: all 0.3s ease;
                cursor: pointer;
            }}
            
            .filters select:hover {{ 
                border-color: rgba(100, 140, 200, 0.3); 
                background: rgba(255, 255, 255, 0.8);
            }}
            
            .filters select:focus {{ 
                outline: none; 
                border-color: rgba(100, 140, 200, 0.5); 
                box-shadow: 0 0 0 3px rgba(100, 140, 200, 0.1);
            }}
            
            table {{ width: 100%; border-collapse: collapse; margin-top: 20px; }}
            th, td {{ padding: 16px 14px; text-align: left; border-bottom: 1px solid rgba(100, 140, 200, 0.1); }}
            td {{ color: #5a6575; font-weight: 500; font-size: 14px; }}
            tr:hover {{ background: rgba(100, 140, 200, 0.04); }}
            th {{ 
                background: rgba(100, 140, 200, 0.08); 
                color: #2d3a4d; 
                font-weight: 700;
                font-size: 13px;
                text-transform: uppercase;
                letter-spacing: 0.5px;
            }}
            
            /* Navigation Tabs */
            .nav-tabs {{
                display: flex;
                gap: 10px;
                margin-bottom: 30px;
                border-bottom: 2px solid rgba(100, 140, 200, 0.15);
                padding-bottom: 0;
                width: fit-content;
                max-width: 100%;
            }}
            .nav-tabs a {{
                padding: 12px 24px;
                text-decoration: none;
                color: #6b7684;
                font-weight: 600;
                font-size: 14px;
                border-bottom: 3px solid transparent;
                transition: all 0.3s ease;
                margin-bottom: -2px;
            }}
            .nav-tabs a:hover {{
                color: #4a5f8f;
                border-bottom-color: rgba(100, 140, 200, 0.3);
            }}
            .nav-tabs a.active {{
                color: #667eea;
                border-bottom-color: #667eea;
            }}

            .mode-badge {{
                display: inline-block;
                padding: 4px 10px;
                border-radius: 999px;
                font-size: 11px;
                font-weight: 700;
                letter-spacing: 0.5px;
                text-transform: uppercase;
                margin-top: 10px;
                width: fit-content;
            }}
            .mode-badge.mode-dev {{
                background: #e0f2fe;
                color: #0c4a6e;
                border: 1px solid #7dd3fc;
            }}
            .mode-badge.mode-prod {{
                background: #dcfce7;
                color: #14532d;
                border: 1px solid #86efac;
            }}
            
            /* Priority Actions Section */
            .priority-actions {{
                margin: 30px 0 40px 0;
                background: linear-gradient(135deg, #fff5f5 0%, #fff9f9 100%);
                border: 2px solid #fecaca;
                border-radius: 12px;
                padding: 24px;
            }}
            .priority-actions-header {{
                display: flex;
                align-items: center;
                gap: 12px;
                margin-bottom: 20px;
                padding-bottom: 16px;
                border-bottom: 2px solid #fecaca;
            }}
            .priority-actions-header h2 {{
                color: #dc2626;
                font-size: 20px;
                font-weight: 700;
                margin: 0;
            }}
            .priority-badge {{
                background: #dc2626;
                color: white;
                padding: 4px 12px;
                border-radius: 20px;
                font-size: 12px;
                font-weight: 700;
            }}
            .action-grid {{
                display: grid;
                grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
                gap: 20px;
            }}
            .action-card {{
                background: white;
                border: 1px solid #fecaca;
                border-radius: 8px;
                padding: 16px;
                transition: all 0.3s ease;
            }}
            .action-card:hover {{
                transform: translateY(-2px);
                box-shadow: 0 4px 12px rgba(220, 38, 38, 0.1);
            }}
            .action-card-header {{
                display: flex;
                align-items: center;
                justify-content: space-between;
                margin-bottom: 12px;
            }}
            .action-card-title {{
                color: #7c2d12;
                font-size: 14px;
                font-weight: 700;
                text-transform: uppercase;
                letter-spacing: 0.5px;
            }}
            .action-count {{
                background: #fee2e2;
                color: #dc2626;
                padding: 2px 8px;
                border-radius: 12px;
                font-size: 12px;
                font-weight: 700;
            }}
            .action-list {{
                list-style: none;
                margin: 0;
                padding: 0;
            }}
            .action-item {{
                padding: 10px 0;
                border-bottom: 1px solid #fef2f2;
            }}
            .action-item:last-child {{
                border-bottom: none;
            }}
            .client-name {{
                font-weight: 600;
                color: #1f2937;
                font-size: 14px;
            }}
            .action-detail {{
                color: #6b7280;
                font-size: 12px;
                margin-top: 4px;
            }}
            .action-metric {{
                color: #dc2626;
                font-weight: 600;
            }}
            .action-button {{
                display: inline-block;
                background: #dc2626;
                color: white;
                padding: 6px 12px;
                border-radius: 4px;
                text-decoration: none;
                font-size: 11px;
                font-weight: 600;
                margin-top: 6px;
                transition: all 0.3s ease;
            }}
            .action-button:hover {{
                background: #b91c1c;
            }}
            .empty-state {{
                text-align: center;
                padding: 30px;
                color: #9ca3af;
                font-size: 14px;
            }}
            
            /* Collapsible Sections - All sections uniformly sized */
            .section-header {{
                cursor: pointer;
                user-select: none;
                display: flex;
                align-items: center;
                justify-content: space-between;
                padding: 14px 18px;
                background: linear-gradient(135deg, rgba(255, 255, 255, 0.78), rgba(246, 249, 253, 0.82));
                border-radius: 8px;
                margin: 12px 0 6px 0;
                font-size: 15px;
                font-weight: 700;
                color: #2d3a4d;
                transition: all 0.3s ease;
                width: 100%;
                box-sizing: border-box;
                border: 1px solid rgba(100, 140, 200, 0.14);
            }}
            .section-header:hover {{
                background: linear-gradient(135deg, rgba(255, 255, 255, 0.92), rgba(241, 246, 252, 0.95));
                border-color: rgba(100, 140, 200, 0.22);
            }}
            .section-toggle {{
                font-size: 16px;
                transition: transform 0.3s ease;
            }}
            .section-toggle.collapsed {{
                transform: rotate(-90deg);
            }}
            .section-content {{
                display: block;
                overflow: visible;
                width: 100%;
                box-sizing: border-box;
            }}
            .section-content.collapsed {{
                display: none;
            }}

            /* Structural wrapper for lower sections */
            .dashboard-sections-wrap {{
                width: 100%;
                margin: 0;
            }}

            /* Safety net: keep centered even if sections escape .container in generated HTML */
            body > .section-header,
            body > .section-content,
            body > .dashboard-sections-wrap,
            body > p {{
                width: var(--dashboard-width);
                max-width: var(--dashboard-max-width);
                margin-left: auto;
                margin-right: auto;
            }}
            
            /* Mobile Responsive */
            @media (max-width: 768px) {{
                body {{ padding: 0; }}
                .container {{ padding: 15px; }}
                .card {{ padding: 16px; margin: 10px 0; }}
                .nav-tabs {{ flex-wrap: wrap; }}
                table {{ font-size: 12px; }}
                table th, table td {{ padding: 10px 8px; }}
            }}
        </style>
        <script>
        function toggleSection(sectionId, headerElement) {{
            const content = document.getElementById(sectionId + '-content');
            const toggle = headerElement ? headerElement.querySelector('.section-toggle') : null;
            if (content && toggle) {{
                content.classList.toggle('collapsed');
                toggle.classList.toggle('collapsed');
            }}
        }}

        function togglePriorityClients(event) {{
            if (event) {{
                event.preventDefault();
                event.stopPropagation();
            }}

            const buttons = document.querySelectorAll('.priorityToggleBtn');
            const extraItems = document.querySelectorAll('.priority-extra-item');
            const countBadge = document.getElementById('priorityCount');
            const headerCount = document.getElementById('priorityHeaderCount');

            if (!buttons.length || extraItems.length === 0) return false;

            const expanded = buttons[0].getAttribute('data-expanded') === 'true';
            const total = parseInt(buttons[0].getAttribute('data-total') || '0', 10);

            if (expanded) {{
                extraItems.forEach(item => item.style.display = 'none');
                buttons.forEach(button => {{
                    button.setAttribute('data-expanded', 'false');
                    button.textContent = `Ver todos (${{total}})`;
                }});
                if (countBadge) countBadge.textContent = '10';
                if (headerCount) headerCount.textContent = ` (10 de ${{total}} clientes)`;
            }} else {{
                extraItems.forEach(item => item.style.display = '');
                buttons.forEach(button => {{
                    button.setAttribute('data-expanded', 'true');
                    button.textContent = 'Ver top 10';
                }});
                if (countBadge) countBadge.textContent = String(total);
                if (headerCount) headerCount.textContent = ` (${{total}} clientes)`;
            }}

            return false;
        }}
        </script>
    </head>
    <body>
        <div class="container">
            <div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 30px;">
                <div style="display: flex; align-items: center; gap: 20px;">
                    <img src="/static/logo.png" alt="Globale RC" style="height: 80px; object-fit: contain;">
                    <div style="display: flex; flex-direction: column; justify-content: center;">
                        <h1 style="font-size: 28px; color: #2d3a4d; margin: 0; font-weight: 700;">Dashboard de Vendas</h1>
                        <p style="font-size: 14px; color: #6b7684; margin: 4px 0 0 0;">{"Minha Área de Vendas: " + ", ".join(assigned_comerciais) if restricted_user and assigned_comerciais else "Globale RC Comercial"}</p>
                        <span class="mode-badge {'mode-prod' if FLASK_MODE == 'production' else 'mode-dev'}">{'PROD' if FLASK_MODE == 'production' else 'DEV'}</span>
                    </div>
                </div>
                <div class="user-info">
                    <span class="user-name">👤 {current_user.name if hasattr(current_user, 'name') and current_user.name else current_user.email.split('@')[0] if hasattr(current_user, 'email') else 'User'}</span>
                    <span class="user-role {user_role.lower() if user_role else ''}">{user_role.upper() if user_role else 'VIEWER'}</span>
                    {'<div style="font-size:11px;color:#6b7684;margin-top:4px;">Demo switcher: ON | View: ' + session.get('test_user_view', 'José Amor') + '</div>' if show_test_view_switcher else ''}
                    {'<div class="test-view-switcher" style="margin-top: 10px;"><label style="font-size: 12px; color: #6b7684; margin-right: 8px;">👁️ Vista de Teste:</label><select id="testViewSelect" style="padding: 4px 8px; border: 1px solid #d1d9e0; border-radius: 4px; font-size: 12px; background: white;"><option value="José Amor"' + (' selected' if session.get('test_user_view', 'José Amor') == 'José Amor' else '') + '>José Amor</option><option value="Hélder Oliveira"' + (' selected' if session.get('test_user_view', 'José Amor') == 'Hélder Oliveira' else '') + '>Hélder Oliveira</option></select></div>' if show_test_view_switcher else ''}
                    <div style="margin-top: 10px;"><a href="/logout" class="logout-btn">Sair</a></div>
                </div>
            </div>
            
            <!-- Navigation Tabs -->
            <nav class="nav-tabs">
                {'<a href="/dashboard" class="active">📊 Vendas</a>' if user_role in ['admin', 'comercial', 'viewer'] else ''}
                {'<a href="/inventory">📦 Inventário</a>' if user_role in ['admin', 'warehouse'] else ''}
            </nav>

            <!-- Admin Controls -->
            {admin_controls_html}

            <!-- Dashboard Sections Wrapper -->
            <div class="dashboard-sections-wrap">

            <!-- Priority Actions Section -->
            <div class="section-header" onclick="toggleSection('priority-actions', this)">
                🎯 Ações Prioritárias da Semana<span id="priorityHeaderCount"> {priority_count_label}</span>
                <span class="section-toggle collapsed">▼</span>
            </div>
            <div class="section-content collapsed" id="priority-actions-content">
            <div class="card">
                <div class="action-grid" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); gap: 16px; margin: 0;">
                
                <!-- Clients with Revenue Drop -->
                <div class="action-card">
                    <div class="action-card-header">
                        <span class="action-card-title">📉 Queda de Faturação (&gt;20%)</span>
                        <span class="action-count" id="priorityCount">{priority_display_count if priority_total_clients else 0}</span>
                    </div>
                    {f'<div style="margin: 6px 0 10px 0; text-align: right;"><a class="priorityToggleBtn" href="#" data-expanded="false" data-total="{priority_total_clients}" onclick="return togglePriorityClients(event);" style="font-size: 12px; color: #667eea; text-decoration: none; font-weight: 600;">Ver todos ({priority_total_clients})</a></div>' if priority_total_clients > 10 else ''}
                    <ul class="action-list">
                        {f'''{''.join([f"""
                        <li class="action-item{' priority-extra-item' if i >= 10 else ''}" style="{'display:none;' if i >= 10 else ''}">
                            <div class="client-name">{client['client_name']}</div>
                            <div class="action-detail">
                                Ano atual: {pah.format_currency(client['current_year_revenue'])}<br>
                                Ano anterior: {pah.format_currency(client['previous_year_revenue'])}<br>
                                Variação: <span class="action-metric">{pah.format_percentage(client['change_pct'])}</span>
                            </div>
                            <a href="#" class="action-button" onclick="alert('Funcionalidade em desenvolvimento'); return false;">📞 Contactar Cliente</a>
                        </li>
                        """ for i, client in enumerate(all_revenue_drop_clients)]) if all_revenue_drop_clients else '<li class="action-item"><div class="empty-state">✓ Sem quedas significativas</div></li>'}'''}
                    </ul>
                    {f'<div style="margin-top: 8px; text-align: right;"><a class="priorityToggleBtn" href="#" data-expanded="false" data-total="{priority_total_clients}" onclick="return togglePriorityClients(event);" style="font-size: 12px; color: #667eea; text-decoration: none; font-weight: 600;">Ver todos ({priority_total_clients})</a></div>' if priority_total_clients > 10 else ''}
                </div>
                
                <!-- Placeholder: Clients Without Recent Visits -->
                <div class="action-card">
                    <div class="action-card-header">
                        <span class="action-card-title">👥 Sem Visitas (45+ dias)</span>
                        <span class="action-count">0</span>
                    </div>
                    <ul class="action-list">
                        <li class="action-item">
                            <div class="empty-state">
                                📋 Sistema de registo de visitas em desenvolvimento<br>
                                <small style="color: #9ca3af; font-size: 11px;">Esta funcionalidade estará disponível em breve</small>
                            </div>
                        </li>
                    </ul>
                </div>
                
                <!-- Placeholder: Upcoming Visits -->
                <div class="action-card">
                    <div class="action-card-header">
                        <span class="action-card-title">📅 Visitas Agendadas (7 dias)</span>
                        <span class="action-count">0</span>
                    </div>
                    <ul class="action-list">
                        <li class="action-item">
                            <div class="empty-state">
                                📋 Sistema de agendamento em desenvolvimento<br>
                                <small style="color: #9ca3af; font-size: 11px;">Esta funcionalidade estará disponível em breve</small>
                            </div>
                        </li>
                    </ul>
                </div>
                </div>
            </div>
            </div>

        <!-- Filters Section -->
        <div class="section-header" onclick="toggleSection('filters', this)">
            🔍 Filtros
            <span class="section-toggle collapsed">▼</span>
        </div>
        <div class="section-content collapsed" id="filters-content">
        <div class="card">
            <div class="label">Filtros</div>
            <p style="color:#666; margin-top:8px; display: flex; align-items: center; gap: 10px; justify-content: space-between;">
                <span>Utilizador: {session.get('user_email') or 'Desconhecido'} | Perfil: {user_role.upper() if user_role else 'DESCONHECIDO'}{'' if not assigned_comerciais else f' | Acesso: {", ".join(assigned_comerciais)}'}</span>
                <a href="/logout" style="padding: 4px 10px; background: #999; color: white; border-radius: 4px; text-decoration: none; font-size: 12px; white-space: nowrap; font-weight: 600;">🚪 Sair</a>
            </p>
            <form method="get" class="filters">
                <select name="year">
                    <option value="all">Todos os Anos</option>
                    {''.join([f'<option value="{y}" {"selected" if y==year_filter else ""}>{y}</option>' for y in years])}
                </select>
                <select name="month">
                    <option value="all">Todos os Meses</option>
                    {''.join([f'<option value="{m}" {"selected" if m==month_filter else ""}>{m}</option>' for m in months])}
                </select>
                <select name="zona">
                    <option value="all">Todas as Zonas</option>
                    {''.join([f'<option value="{z}" {"selected" if z==zona_filter else ""}>{z}</option>' for z in zonas])}
                </select>
                <select name="comercial">
                    <option value="all">Todos os Comerciais</option>
                    {''.join([f'<option value="{c}" {"selected" if c==comercial_filter else ""}>{c}</option>' for c in comerciais])}
                </select>
                <select name="familia">
                    <option value="all">Todas as Famílias</option>
                    {''.join([f'<option value="{f}" {"selected" if f==familia_filter else ""}>{f}</option>' for f in familias])}
                </select>
                <select name="cliente">
                    <option value="all">Todos os Clientes</option>
                    {''.join([f'<option value="{c}" {"selected" if c==cliente_filter else ""}>{c}</option>' for c in clientes])}
                </select>
                <button type="submit" style="grid-column: 1 / -1; padding: 12px 18px; border: none; background: linear-gradient(135deg, rgba(100, 140, 200, 0.2), rgba(100, 140, 200, 0.08)); color: #4a5f8f; border: 1px solid rgba(100, 140, 200, 0.2); border-radius: 6px; cursor: pointer; font-weight: 600; font-size: 14px; transition: all 0.3s ease;" onmouseover="this.style.borderColor='rgba(100, 140, 200, 0.4)'; this.style.background='linear-gradient(135deg, rgba(100, 140, 200, 0.3), rgba(100, 140, 200, 0.12))'" onmouseout="this.style.borderColor='rgba(100, 140, 200, 0.2)'; this.style.background='linear-gradient(135deg, rgba(100, 140, 200, 0.2), rgba(100, 140, 200, 0.08))'" >Aplicar Filtros</button>
            </form>
            <div style="margin-top: 20px; display: flex; gap: 12px; flex-wrap: wrap; align-items: center;">
                {'<a href="/debug/comercial-email-mapping" style="padding: 12px 18px; background: linear-gradient(135deg, rgba(100, 140, 200, 0.2), rgba(100, 140, 200, 0.08)); color: #4a5f8f; border-radius: 6px; text-decoration: none; text-align: center; font-weight: 600; font-size: 14px; white-space: nowrap; border: 1px solid rgba(100, 140, 200, 0.2); transition: all 0.3s ease;">📧 Verificar Mapeamento Email</a>' if user_email in ADMIN_EMAILS else ''}
            </div>
        </div>
        </div> <!-- end filters section -->

        <div class="section-header" onclick="toggleSection('projecoes', this)">
            🎯 Projeções, Objetivos e vendas
            <span class="section-toggle collapsed">▼</span>
        </div>
        <div class="section-content collapsed" id="projecoes-content">
        <div class="card">
            <div class="label">Projeções, Objetivos e vendas</div>
            <div style="margin-top: 20px; display: flex; gap: 12px; flex-wrap: wrap; align-items: center;">
                {annual_report_link}
            </div>
                {f'''<div style="margin-top: 18px; display: flex; flex-wrap: wrap; gap: 12px; align-items: center; background: rgba(100, 140, 200, 0.06); border: 1px solid rgba(100, 140, 200, 0.15); border-radius: 6px; padding: 14px 16px;">
                    <span style="font-size: 12px; font-weight: 700; color: #4a5f8f; text-transform: uppercase; letter-spacing: 0.5px;">🎯 Planeamento de Objetivos Comerciais</span>
                    <a href="/salesforce-objectives-planner" style="padding: 10px 14px; background: linear-gradient(135deg, rgba(100, 140, 200, 0.22), rgba(100, 140, 200, 0.10)); color: #4a5f8f; border-radius: 6px; border: 1px solid rgba(100, 140, 200, 0.25); text-decoration: none; font-weight: 600; font-size: 13px; white-space: nowrap;">⚙️ Abrir Planeador de Objetivos</a>
                    <a href="/admin-objectives-tracking" style="padding: 10px 14px; background: linear-gradient(135deg, rgba(16, 185, 129, 0.22), rgba(16, 185, 129, 0.10)); color: #047857; border-radius: 6px; border: 1px solid rgba(16, 185, 129, 0.25); text-decoration: none; font-weight: 600; font-size: 13px; white-space: nowrap;">📊 Ver Acompanhamento</a>
                    <span style="font-size: 12px; color: #5f6f8f;">Substitui o fluxo antigo e permite definir metas globais + distribuição justa por comercial.</span>
                </div>''' if user_role == 'admin' else ''}
            </div>
        </div>
        </div> <!-- end projections section -->

        <!-- top and lower sections share the same wrapper for consistent alignment -->

        <div class="section-header" onclick="toggleSection('last3', this)">
            📋 Resultados dos Últimos 3 Anos
            <span class="section-toggle collapsed">▼</span>
        </div>
        <div class="section-content collapsed" id="last3-content">
        <div class="card">
            <div class="label">Resultados dos Últimos 3 Anos</div>
            <table>
                <tr><th>Ano</th><th>Faturação</th><th>Crescimento vs Ant</th><th>Média €/URNA (Total)</th><th>Crescimento</th><th>Média €/URNA (URNAS)</th><th>Crescimento</th><th>Clientes</th></tr>
                {last3_rows_html}
            </table>
        </div>
        </div>

        <div class="section-header" onclick="toggleSection('monthly', this)">
            📋 Faturação Mensal (Últimos 12)
            <span class="section-toggle collapsed">▼</span>
        </div>
        <div class="section-content collapsed" id="monthly-content">
        <div class="card">
            <div class="label">Faturação Mensal (Últimos 12)</div>
            <table>
                <tr><th>Período</th><th>Faturação</th></tr>
                {''.join([f'<tr><td>{p}</td><td>€{v:,.2f}</td></tr>' for p, v in monthly])}
            </table>
        </div>
        </div>

        <div class="section-header" onclick="toggleSection('zonas', this)">
            📋 Zonas
            <span class="section-toggle collapsed">▼</span>
        </div>
        <div class="section-content collapsed" id="zonas-content">
        <div class="card">
            <div class="label">Zonas</div>
            <table>
                <tr><th>Zona</th><th>Faturação</th><th>Clientes</th></tr>
                {''.join([f'<tr style="cursor: pointer; transition: all 0.2s ease;" onmouseover="this.style.backgroundColor=\'rgba(100, 140, 200, 0.08)\'" onmouseout="this.style.backgroundColor=\'transparent\'" onclick="window.location.href=\'/zona-clients?zona={quote_plus(str(z))}&{filter_qs}\'"><td><strong style="color: #4a5f8f;">{z}</strong></td><td>€{v:,.2f}</td><td><a href="/zona-clients?zona={quote_plus(str(z))}&{filter_qs}" style="color:#667eea;text-decoration:none; font-size: 13px;">Ver →</a></td></tr>' for z, v in by_zona])}
            </table>
        </div>
        </div>

        <div class="section-header" onclick="toggleSection('clients-summary', this)">
            📋 Resumo de Clientes
            <span class="section-toggle collapsed">▼</span>
        </div>
        <div class="section-content collapsed" id="clients-summary-content">
        <div class="card">
            <div class="label">Resumo de Clientes</div>
            <table>
                <tr><th>Cliente</th><th>Faturação</th><th>Quantidade</th><th>Ações</th></tr>
                {''.join([f'<tr><td>{c}</td><td>€{f:,.2f}</td><td>{int(q):,}</td><td><a href="/client-details?cliente={quote_plus(str(c))}&{filter_qs}" style="color:#667eea;text-decoration:none;margin-right:8px;">Ver →</a><a href="/client-intelligence?cliente={quote_plus(str(c))}" style="color:white;text-decoration:none;background:linear-gradient(135deg,#667eea,#764ba2);padding:4px 10px;border-radius:3px;font-size:11px;font-weight:600;display:inline-block;">📊 Intel</a></td></tr>' for c, f, q in clients_summary])}
            </table>
        </div>
        </div>

        {"" if restricted_user else f'''
        <div class="section-header" onclick="toggleSection('top-comerciais', this)">
            📋 Top 10 Comerciais
            <span class="section-toggle collapsed">▼</span>
        </div>
        <div class="section-content collapsed" id="top-comerciais-content">
        <div class="card">
            <div class="label">Top 10 Comerciais</div>
            <table>
                <tr><th>Comercial</th><th>Faturação</th></tr>
                {''.join([f'<tr><td>{c}</td><td>€{v:,.2f}</td></tr>' for c, v in by_comercial])}
            </table>
        </div>
        </div>
        '''}

        <div class="section-header" onclick="toggleSection('top-familias', this)">
            📋 Top 10 Famílias
            <span class="section-toggle collapsed">▼</span>
        </div>
        <div class="section-content collapsed" id="top-familias-content">
        <div class="card">
            <div class="label">Top 10 Famílias</div>
            <table>
                <tr><th>Família</th><th>Faturação</th></tr>
                {''.join([f'<tr><td>{f}</td><td>€{v:,.2f}</td></tr>' for f, v in by_familia])}
            </table>
        </div>
        </div>

        <div class="section-header" onclick="toggleSection('products-qty', this)">
            📋 Top 20 Produtos por Quantidade (Urnas)
            <span class="section-toggle collapsed">▼</span>
        </div>
        <div class="section-content collapsed" id="products-qty-content">
        <div class="card">
            <div class="label">Top 20 Produtos por Quantidade (Urnas)</div>
            <table>
                <tr><th>Referência</th><th>Quantidade</th></tr>
                {''.join([f'<tr><td>{r}</td><td>{int(q):,}</td></tr>' for r, q in by_product_qty])}
            </table>
        </div>
        </div>

        <div class="section-header" onclick="toggleSection('products-revenue', this)">
            📋 Top 20 Produtos por Faturação
            <span class="section-toggle collapsed">▼</span>
        </div>
        <div class="section-content collapsed" id="products-revenue-content">
        <div class="card">
            <div class="label">Top 20 Produtos por Faturação</div>
            <table>
                <tr><th>Referência</th><th>Faturação</th></tr>
                {''.join([f'<tr><td>{r}</td><td>€{v:,.2f}</td></tr>' for r, v in by_product_rev])}
            </table>
        </div>
        </div>

        </div> <!-- end dashboard-sections-wrap -->

        <p><a href="/logout">Sair</a></p>
        </div> <!-- close wrapper -->
        
        {'<script>' if show_test_view_switcher else ''}
        {'// Test user view switcher' if show_test_view_switcher else ''}
        {'document.getElementById("testViewSelect").addEventListener("change", async function() {' if show_test_view_switcher else ''}
        {'    const selectedView = this.value;' if show_test_view_switcher else ''}
        {'    try {' if show_test_view_switcher else ''}
        {'        const response = await fetch("/switch-test-view", {' if show_test_view_switcher else ''}
        {'            method: "POST",' if show_test_view_switcher else ''}
        {'            headers: { "Content-Type": "application/json" },' if show_test_view_switcher else ''}
        {'            body: JSON.stringify({ view: selectedView })' if show_test_view_switcher else ''}
        {'        });' if show_test_view_switcher else ''}
        {'        const data = await response.json();' if show_test_view_switcher else ''}
        {'        if (data.success) {' if show_test_view_switcher else ''}
        {'            window.location.reload();' if show_test_view_switcher else ''}
        {'        } else {' if show_test_view_switcher else ''}
        {'            alert("Erro ao alterar vista: " + data.error);' if show_test_view_switcher else ''}
        {'        }' if show_test_view_switcher else ''}
        {'    } catch (error) {' if show_test_view_switcher else ''}
        {'        console.error("Error switching view:", error);' if show_test_view_switcher else ''}
        {'        alert("Erro ao alterar vista. Verifique a consola.");' if show_test_view_switcher else ''}
        {'    }' if show_test_view_switcher else ''}
        {'});' if show_test_view_switcher else ''}
        {'</script>' if show_test_view_switcher else ''}
    </body>
    </html>
    """
    response = Response(html)
    response.headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0'
    response.headers['Pragma'] = 'no-cache'
    response.headers['Expires'] = '0'
    return response

@app.route('/zona-clients')
@login_required
def zona_clients():
    """Show all clients from a specific zona."""
    zona_name = request.args.get('zona')
    if not zona_name:
        return redirect(url_for('dashboard'))
    
    df = fetch_data()
    if df is None:
        return "Erro ao carregar dados", 500
    
    def find_col(*keywords):
        for col in df.columns:
            name = col.lower()
            if all(k in name for k in keywords):
                return col
        return None
    
    zona_col = find_col('zona')
    cliente_col = find_col('cliente')
    fat_col = find_col('fatura')
    quant_col = find_col('quant')
    comercial_col = find_col('comercial')
    familia_col = find_col('familia') or find_col('família')
    mes_col = find_col('mês') or find_col('mes')
    
    if not zona_col or not cliente_col:
        return "Coluna de Zona ou Cliente não encontrada", 500
    
    # Build year/month columns from mes_col (for filtering)
    if mes_col:
        def parse_period(value):
            if value is None:
                return (None, None)
            s = str(value).strip()
            if not s:
                return (None, None)
            s = s.replace('-', '/').replace('.', '/')
            m = re.search(r"(\d{4})\D?(\d{1,2})", s)
            if m:
                year = m.group(1)
                month = m.group(2).zfill(2)
                return (year, month)
            m = re.search(r"(\d{1,2})\D?(\d{4})", s)
            if m:
                month = m.group(1).zfill(2)
                year = m.group(2)
                return (year, month)
            return (None, None)

        ym = df[mes_col].apply(parse_period)
        df['__year'] = ym.apply(lambda x: x[0])
        df['__month'] = ym.apply(lambda x: x[1])
    else:
        df['__year'] = None
        df['__month'] = None
    
    # Access control based on user role
    user_email = session.get('user_email')
    user_role = get_user_role(user_email) if user_email else None
    
    # Filter to this zona
    zona_data = df[df[zona_col] == zona_name].copy()
    
    # Apply dashboard filters (year, month, comercial, familia) - default to current year
    current_year_str = str(datetime.now().year)
    year_filter = request.args.get('year', current_year_str if current_year_str in df['__year'].astype(str).values else 'all')
    month_filter = request.args.get('month', 'all')
    comercial_filter = request.args.get('comercial', 'all')
    familia_filter = request.args.get('familia', 'all')
    
    if year_filter != 'all':
        zona_data = zona_data[zona_data['__year'] == year_filter]
    if month_filter != 'all':
        zona_data = zona_data[zona_data['__month'] == month_filter]
    if comercial_col and comercial_filter != 'all':
        zona_data = zona_data[zona_data[comercial_col] == comercial_filter]
    if familia_col and familia_filter != 'all':
        zona_data = zona_data[zona_data[familia_col] == familia_filter]
    
    # For comercial users: only show their own clients' data
    if user_role == 'comercial' and user_email in SALES_ACCESS_MAP:
        assigned = get_user_comercials(user_email)
        allowed = [a.strip().lower() for a in assigned]
        if comercial_col:
            zona_data = zona_data[
                zona_data[comercial_col].astype(str).str.strip().str.lower().isin(allowed)
            ]
    
    if zona_data.empty:
        return f"<html><body><h1>Sem clientes na zona: {zona_name}</h1><p><a href='/dashboard'>← Voltar ao Dashboard</a></p></body></html>"
    
    # Build filter querystring for client links
    filter_params = []
    if year_filter != 'all':
        filter_params.append(f'year={year_filter}')
    if month_filter != 'all':
        filter_params.append(f'month={month_filter}')
    if comercial_filter != 'all':
        filter_params.append(f'comercial={quote_plus(comercial_filter)}')
    if familia_filter != 'all':
        filter_params.append(f'familia={quote_plus(familia_filter)}')
    filter_params.append(f'zona={quote_plus(zona_name)}')
    filter_qs = '&'.join(filter_params)
    
    # Get clients in this zona with their totals (URNAS-only for quantity)
    clients_list = []
    for cliente in zona_data[cliente_col].unique():
        if pd.isna(cliente):
            continue
        client_subset = zona_data[zona_data[cliente_col] == cliente]
        total_fat = client_subset[fat_col].sum() if fat_col else 0
        
        # Calculate URNAS-only quantity for this client
        if familia_col and quant_col:
            client_urnas = filter_urnas_family_rows(client_subset, familia_col)
            total_quant = client_urnas[quant_col].sum() if not client_urnas.empty else 0
        else:
            total_quant = client_subset[quant_col].sum() if quant_col else 0
        
        clients_list.append({
            'name': str(cliente),
            'revenue': total_fat,
            'quantity': total_quant
        })
    
    # Sort by revenue descending
    clients_list.sort(key=lambda x: x['revenue'], reverse=True)
    
    # Total summary - filtered revenue, URNAS-only quantity
    total_zona_revenue = zona_data[fat_col].sum() if fat_col else 0
    
    # Calculate URNAS-only quantity
    urnas_data = filter_urnas_family_rows(zona_data, familia_col) if familia_col else zona_data
    total_zona_quantity = urnas_data[quant_col].sum() if quant_col and not urnas_data.empty else 0
    
    num_clients = len(clients_list)
    
    # Top 10 URNAS references for this zona
    referencia_col = find_col('referencia')
    top_urnas = []
    if referencia_col and quant_col and not urnas_data.empty:
        def normalize_ref(value):
            s = str(value).strip()
            if not s:
                return s
            m = re.match(r'^[Cc]\s*(\d+)$', s)
            if m:
                return m.group(1)
            m = re.match(r'^(\d+)$', s)
            if m:
                return m.group(1)
            return s
        
        special_merge = {'122', '124', '126'}
        
        def build_ref_display(norm, refs):
            refs_clean = [str(v).strip() for v in refs if str(v).strip()]
            if norm == '122_124_126':
                return " / ".join(sorted(set(refs_clean)))
            return str(norm)
        
        urnas_norm = urnas_data.assign(
            __ref_norm=urnas_data[referencia_col].apply(normalize_ref),
            __ref_orig=urnas_data[referencia_col].astype(str).str.strip()
        )
        urnas_norm['__ref_group'] = urnas_norm['__ref_norm'].apply(
            lambda r: '122_124_126' if str(r) in special_merge else str(r)
        )
        
        grouped_qty = (
            urnas_norm.groupby('__ref_group')
            .agg(
                __qty=(quant_col, 'sum'),
                __refs=('__ref_orig', lambda x: list({v for v in x if v}))
            )
        )
        grouped_qty['__display'] = grouped_qty.apply(
            lambda row: build_ref_display(row.name, row['__refs']), axis=1
        )
        top_urnas = (
            grouped_qty.sort_values(by='__qty', ascending=False)
            .head(10)
            .reset_index(drop=True)
            [['__display', '__qty']]
            .values.tolist()
        )
    
    # Build HTML with filter parameters in client links
    clients_rows = ''.join([
        f'<tr><td><a href="/client-details?cliente={quote_plus(str(c["name"]))}&{filter_qs}" style="color:#667eea;text-decoration:none;">{c["name"]}</a></td>'
        f'<td>€{c["revenue"]:,.2f}</td><td>{int(c["quantity"]):,}</td></tr>'
        for c in clients_list
    ])
    
    # Build top urnas rows
    urnas_rows = ''.join([
        f'<tr><td>{ref}</td><td>{int(qty):,}</td></tr>'
        for ref, qty in top_urnas
    ]) if top_urnas else '<tr><td colspan="2" style="text-align: center; color: #6b7684;">Sem dados</td></tr>'
    
    report_timestamp = datetime.now().strftime("%d/%m/%Y %H:%M")
    
    html = f'''
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>Zona: {zona_name}</title>
        <style>
            * {{
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }}
            body {{
                font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
                background: #f5f5f5;
                padding: 20px;
                color: #333;
            }}
            
            .header {{ 
                background: white; 
                padding: 20px; 
                margin-bottom: 20px; 
                border-radius: 8px; 
                box-shadow: 0 2px 4px rgba(0,0,0,0.1);
                display: flex;
                justify-content: space-between;
                align-items: center;
                border-top: 4px solid #667eea;
            }}
            
            .header-left {{ display: flex; align-items: center; gap: 15px; }}
            .header-info h1 {{ color: #333; font-size: 24px; margin-bottom: 5px; }}
            .header-info p {{ color: #888; font-size: 14px; }}
            
            .header-right {{ text-align: right; }}
            .timestamp {{ color: #666; font-size: 13px; margin-bottom: 10px; }}
            
            .button-group {{ display: flex; gap: 10px; }}
            .btn {{ 
                padding: 10px 16px; 
                border: none; 
                border-radius: 6px; 
                font-size: 14px; 
                cursor: pointer; 
                font-weight: 600;
                transition: all 0.3s ease;
                text-decoration: none;
                display: inline-flex;
                align-items: center;
                gap: 6px;
            }}
            
            .btn-print {{ 
                background: #667eea; 
                color: white;
            }}
            .btn-print:hover {{ background: #5568d3; }}
            
            .btn-back {{ 
                background: #e5e7eb; 
                color: #333;
            }}
            .btn-back:hover {{ background: #d1d5db; }}
            
            .container {{ max-width: 1200px; margin: 0 auto; }}
            
            .card {{ background: white; padding: 20px; margin: 10px 0; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }}
            .grid {{ display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 16px; }}
            h2 {{ color: #333; font-size: 18px; margin-bottom: 10px; }}
            .stat-box {{ background: linear-gradient(135deg, rgba(100, 140, 200, 0.15), rgba(100, 140, 200, 0.05)); color: #4a5f8f; padding: 20px; border-radius: 8px; border: 1px solid rgba(100, 140, 200, 0.2); text-align: center; }}
            .stat-value {{ font-size: 28px; font-weight: bold; color: #667eea; }}
            .stat-label {{ font-size: 13px; color: #888; margin-top: 8px; text-transform: uppercase; }}
            table {{ width: 100%; border-collapse: collapse; }}
            th, td {{ padding: 12px; text-align: left; border-bottom: 1px solid #ddd; }}
            th {{ background: #667eea; color: white; font-weight: 600; }}
            td {{ color: #333; }}
            a {{ color: #667eea; text-decoration: none; }}
            a:hover {{ text-decoration: underline; }}
            
            .filter-info {{
                background: rgba(100, 140, 200, 0.08);
                padding: 12px 16px;
                border-radius: 6px;
                margin-bottom: 20px;
                border: 1px solid rgba(100, 140, 200, 0.15);
                font-size: 13px;
                color: #4a5f8f;
            }}
            .filter-info strong {{
                color: #2c3e50;
            }}
            
            @media print {{
                body {{ background: white; padding: 0; }}
                .header {{ border: 1px solid #ddd; margin-bottom: 15px; }}
                .button-group {{ display: none; }}
                .card {{ page-break-inside: avoid; }}
                .filter-info {{ page-break-inside: avoid; }}
            }}
        </style>
    </head>
    <body>
        <div class="header">
            <div class="header-left">
                <img src="/static/logo.png" alt="Globale RC" class="logo" style="height: 50px; object-fit: contain;">
                <div class="header-info">
                    <h1>Zona: {zona_name}</h1>
                    <p>Análise Detalhada da Zona</p>
                </div>
            </div>
            <div class="header-right">
                <div class="timestamp">Gerado em: {report_timestamp}</div>
                <div style="font-size: 13px; color: #666; margin-bottom: 10px;">
                    <strong>📊 Origem dos Dados:</strong> Ano: <strong>{year_filter if year_filter != 'all' else 'Todos os Anos'}</strong>
                    {f" | Mês: <strong>{month_filter}</strong>" if month_filter != 'all' else ''}
                    {f" | Comercial: <strong>{comercial_filter}</strong>" if comercial_filter != 'all' else ''}
                    {f" | Família: <strong>{familia_filter}</strong>" if familia_filter != 'all' else ''}
                </div>
                <div class="button-group">
                    <button class="btn btn-print" onclick="window.print()">🖨️ Imprimir</button>
                    <a href="/dashboard" class="btn btn-back">← Dashboard</a>
                </div>
            </div>
        </div>
        
        <div class="container">
            <div class="filter-info">
                <strong>📋 Origem dos Dados:</strong> 
                Ano: <strong>{year_filter if year_filter != 'all' else 'Todos os Anos'}</strong>
                {f" | Mês: <strong>{month_filter}</strong>" if month_filter != 'all' else ''}
                {f" | Comercial: <strong>{comercial_filter}</strong>" if comercial_filter != 'all' else ''}
                {f" | Família: <strong>{familia_filter}</strong>" if familia_filter != 'all' else ''}
            </div>
            
            <div class="grid">
                <div class="stat-box">
                    <div class="stat-label">Faturação Total</div>
                    <div class="stat-value">€{total_zona_revenue:,.2f}</div>
                </div>
                <div class="stat-box">
                    <div class="stat-label">Quantidade Urnas</div>
                    <div class="stat-value">{int(total_zona_quantity):,}</div>
                </div>
                <div class="stat-box">
                    <div class="stat-label">Clientes</div>
                    <div class="stat-value">{num_clients}</div>
                </div>
            </div>
            
            <div class="card">
                <h2>🏆 Top 10 Urnas (Referências)</h2>
                <table>
                    <tr>
                        <th>Referência</th>
                        <th>Quantidade</th>
                    </tr>
                    {urnas_rows}
                </table>
            </div>
            
            <div class="card">
                <h2>👥 Clientes desta Zona</h2>
                <table>
                    <tr>
                        <th>Cliente</th>
                        <th>Faturação</th>
                        <th>Quantidade (Urnas)</th>
                    </tr>
                    {clients_rows}
                </table>
            </div>
        </div>
    </body>
    </html>
    '''
    return html

def generate_visit_reports_section(cliente_name, comercial_name):
    """Generate HTML for visit reports section with form and history"""
    
    # Fetch existing visit reports
    visit_reports_df = fetch_visit_reports(cliente_name)
    
    # Convert to list of dicts for easier template rendering
    visit_reports = []
    if not visit_reports_df.empty:
        visit_reports = visit_reports_df.to_dict('records')
        # Sort by date descending (most recent first)
        visit_reports.sort(key=lambda x: x.get('Data Visita', ''), reverse=True)
    
    # Generate reports table HTML
    reports_html = ""
    if visit_reports:
        for idx, report in enumerate(visit_reports):
            status_color = '#4CAF50' if report.get('Status') == 'Concluído' else '#FF9800' if report.get('Status') == 'Pendente' else '#2196F3'
            reports_html += f"""
            <div style="background: #f9f9f9; padding: 15px; border-left: 4px solid {status_color}; margin-bottom: 12px; border-radius: 4px;">
                <div style="display: flex; justify-content: space-between; align-items: start; margin-bottom: 8px;">
                    <div>
                        <strong style="font-size: 16px; color: #333;">Visita em {report.get('Data Visita', 'N/A')}</strong>
                        <span style="background: {status_color}; color: white; padding: 3px 8px; border-radius: 3px; font-size: 12px; margin-left: 10px;">
                            {report.get('Status', 'Desconhecido')}
                        </span>
                    </div>
                    <span style="color: #999; font-size: 12px;">{report.get('Data Criação', 'N/A')}</span>
                </div>
                <p style="color: #666; margin: 5px 0;"><strong>Tipo:</strong> {report.get('Tipo Visita', 'N/A')}</p>
                <p style="color: #666; margin: 5px 0;"><strong>Comercial:</strong> {report.get('Comercial', 'N/A')}</p>
                <p style="color: #333; margin: 8px 0; line-height: 1.5;"><strong>Resumo:</strong> {report.get('Resumo', 'N/A')}</p>
                <p style="color: #333; margin: 8px 0; line-height: 1.5;"><strong>Próximas Ações:</strong> {report.get('Próximas Ações', 'N/A')}</p>
                {f'<p style="color: #666; margin: 5px 0;"><strong>Data de Seguimento:</strong> {report.get("Data Seguimento", "")}</p>' if report.get('Data Seguimento') else ''}
                {f'<p style="color: #666; margin: 5px 0;"><strong>Orçamento/Deal:</strong> €{report.get("Orçamento", "")}</p>' if report.get('Orçamento') else ''}
                {f'<p style="color: #666; margin: 5px 0;"><strong>Produtos:</strong> {report.get("Produtos", "")}</p>' if report.get('Produtos') else ''}
            </div>
            """
    else:
        reports_html = '<p style="color: #999; font-style: italic;">Sem relatórios de visita registados.</p>'
    
    html = f"""
    <div class="card" style="margin-top: 30px;">
        <h2>📋 Relatórios de Visita</h2>
        
        <div style="margin-bottom: 25px; padding: 20px; background: #f0f4ff; border-radius: 8px; border: 1px solid #e0e8ff;">
            <h3 style="margin-top: 0; color: #333;">Registar Nova Visita</h3>
            
            <form id="visitReportForm" style="display: grid; gap: 12px;">
                <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px;">
                    <div>
                        <label style="display: block; margin-bottom: 5px; font-weight: 500; color: #333;">Data da Visita *</label>
                        <input type="date" id="visit_date" name="visit_date" required 
                               style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 14px;">
                    </div>
                    <div>
                        <label style="display: block; margin-bottom: 5px; font-weight: 500; color: #333;">Tipo de Visita</label>
                        <select id="visit_type" name="visit_type" 
                                style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 14px;">
                            <option value="">-- Selecionar --</option>
                            <option value="Contacto Inicial">Contacto Inicial</option>
                            <option value="Seguimento">Seguimento</option>
                            <option value="Negociação">Negociação</option>
                            <option value="Acordo">Acordo</option>
                            <option value="Resolução de Problema">Resolução de Problema</option>
                            <option value="Outro">Outro</option>
                        </select>
                    </div>
                </div>
                
                <div>
                    <label style="display: block; margin-bottom: 5px; font-weight: 500; color: #333;">Resumo *</label>
                    <textarea id="summary" name="summary" required rows="3" 
                              placeholder="O que foi discutido durante a visita..."
                              style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 14px; font-family: inherit;"></textarea>
                </div>
                
                <div>
                    <label style="display: block; margin-bottom: 5px; font-weight: 500; color: #333;">Próximas Ações *</label>
                    <textarea id="next_actions" name="next_actions" required rows="2" 
                              placeholder="O que precisa ser feito a seguir..."
                              style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 14px; font-family: inherit;"></textarea>
                </div>
                
                <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px;">
                    <div>
                        <label style="display: block; margin-bottom: 5px; font-weight: 500; color: #333;">Estado</label>
                        <select id="status" name="status" 
                                style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 14px;">
                            <option value="Pendente">Pendente</option>
                            <option value="Concluído">Concluído</option>
                            <option value="Agendado">Agendado</option>
                        </select>
                    </div>
                    <div>
                        <label style="display: block; margin-bottom: 5px; font-weight: 500; color: #333;">Data de Seguimento</label>
                        <input type="date" id="followup_date" name="followup_date" 
                               style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 14px;">
                    </div>
                </div>
                
                <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px;">
                    <div>
                        <label style="display: block; margin-bottom: 5px; font-weight: 500; color: #333;">Orçamento/Valor</label>
                        <input type="text" id="budget" name="budget" placeholder="Ex: €5.000"
                               style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 14px;">
                    </div>
                    <div>
                        <label style="display: block; margin-bottom: 5px; font-weight: 500; color: #333;">Produtos Discutidos</label>
                        <input type="text" id="products" name="products" placeholder="Ex: Urnas, Serviços"
                               style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; font-size: 14px;">
                    </div>
                </div>
                
                <button type="submit" 
                        style="background: #667eea; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; font-weight: 500;">
                    💾 Guardar Relatório de Visita
                </button>
                <div id="formMessage" style="display: none; padding: 10px; border-radius: 4px; margin-top: 10px;"></div>
            </form>
            
            <script>
            document.getElementById('visitReportForm').addEventListener('submit', async function(e) {{
                e.preventDefault();
                
                const formData = {{
                    cliente: '{cliente_name}',
                    comercial: '{comercial_name}',
                    visit_date: document.getElementById('visit_date').value,
                    visit_type: document.getElementById('visit_type').value || 'Não especificado',
                    summary: document.getElementById('summary').value,
                    next_actions: document.getElementById('next_actions').value,
                    status: document.getElementById('status').value,
                    followup_date: document.getElementById('followup_date').value,
                    budget: document.getElementById('budget').value,
                    products: document.getElementById('products').value
                }};
                
                const msgDiv = document.getElementById('formMessage');
                msgDiv.style.display = 'block';
                
                try {{
                    const response = await fetch('/save-visit-report', {{
                        method: 'POST',
                        headers: {{'Content-Type': 'application/json'}},
                        body: JSON.stringify(formData)
                    }});
                    
                    const result = await response.json();
                    
                    if (result.success) {{
                        msgDiv.style.background = '#4CAF50';
                        msgDiv.style.color = 'white';
                        msgDiv.textContent = '✓ ' + result.message;
                        document.getElementById('visitReportForm').reset();
                        // Reload page after 2 seconds
                        setTimeout(() => location.reload(), 2000);
                    }} else {{
                        msgDiv.style.background = '#f44336';
                        msgDiv.style.color = 'white';
                        msgDiv.textContent = '✗ ' + result.error;
                    }}
                }} catch (error) {{
                    msgDiv.style.background = '#f44336';
                    msgDiv.style.color = 'white';
                    msgDiv.textContent = '✗ Erro: ' + error.message;
                }}
            }});
            </script>
        </div>
        
        <h3 style="margin-top: 20px; margin-bottom: 15px; color: #333;">Histórico de Visitas</h3>
        {reports_html}
    </div>
    """
    
    return html

@app.route('/client-details')
@login_required
def client_details():
    """Show detailed breakdown for a specific client."""
    cliente_name = request.args.get('cliente')
    if not cliente_name:
        return redirect(url_for('dashboard'))
    
    df = fetch_data()
    if df is None:
        return "Error loading data", 500
    
    def find_col(*keywords):
        for col in df.columns:
            name = col.lower()
            if all(k in name for k in keywords):
                return col
        return None
    
    cliente_col = find_col('cliente')
    referencia_col = find_col('referencia')
    fat_col = find_col('fatura')
    quant_col = find_col('quant')
    mes_col = find_col('mês') or find_col('mes')
    familia_col = find_col('familia') or find_col('família')
    desconto_col = find_col('desconto')
    prazo_col = find_col('prazo', 'pagamento') or find_col('prazo')
    
    if not cliente_col:
        return "Cliente column not found", 500
    
    # Build year/month columns from mes_col (for filtering)
    if mes_col:
        def parse_period(value):
            if value is None:
                return (None, None)
            s = str(value).strip()
            if not s:
                return (None, None)
            s = s.replace('-', '/').replace('.', '/')
            m = re.search(r"(\d{4})\D?(\d{1,2})", s)
            if m:
                year = m.group(1)
                month = m.group(2).zfill(2)
                return (year, month)
            m = re.search(r"(\d{1,2})\D?(\d{4})", s)
            if m:
                month = m.group(1).zfill(2)
                year = m.group(2)
                return (year, month)
            return (None, None)

        ym = df[mes_col].apply(parse_period)
        df['__year'] = ym.apply(lambda x: x[0])
        df['__month'] = ym.apply(lambda x: x[1])
    else:
        df['__year'] = None
        df['__month'] = None

    # Filter to this client
    client_data = df[df[cliente_col] == cliente_name]

    # Apply filters from dashboard - default to current year
    current_year_str = str(datetime.now().year)
    year_filter = request.args.get('year', current_year_str if current_year_str in df['__year'].astype(str).values else 'all')
    month_filter = request.args.get('month', 'all')
    zona_filter = request.args.get('zona', 'all')
    comercial_filter = request.args.get('comercial', 'all')
    familia_filter = request.args.get('familia', 'all')
    zona_col = find_col('zona')
    comercial_col = find_col('comercial')

    if year_filter != 'all':
        client_data = client_data[client_data['__year'] == year_filter]
    if month_filter != 'all':
        client_data = client_data[client_data['__month'] == month_filter]
    if zona_col and zona_filter != 'all':
        client_data = client_data[client_data[zona_col] == zona_filter]
    if comercial_col and comercial_filter != 'all':
        client_data = client_data[client_data[comercial_col] == comercial_filter]
    if familia_col and familia_filter != 'all':
        client_data = client_data[client_data[familia_col] == familia_filter]
    
    # Access control based on user role
    user_email = session.get('user_email')
    user_role = get_user_role(user_email) if user_email else None
    
    # For comercial users: only show their own clients' data
    if user_role == 'comercial' and user_email in SALES_ACCESS_MAP:
        assigned = get_user_comercials(user_email)
        allowed = [a.strip().lower() for a in assigned]
        if comercial_col:
            client_data = client_data[
                client_data[comercial_col].astype(str).str.strip().str.lower().isin(allowed)
            ]
    
    if client_data.empty:
        return f"<html><body><h1>No data for client: {cliente_name}</h1><p><a href='/dashboard'>← Back</a></p></body></html>"
    
    # Get comercial name
    comercial_name = "Not Assigned"
    if comercial_col:
        comerciais = client_data[comercial_col].dropna().unique()
        if len(comerciais) > 0:
            comercial_name = comerciais[0]
    
    # Totals
    total_fat = client_data[fat_col].sum() if fat_col else 0
    total_quant = client_data[quant_col].sum() if quant_col else 0

    # Averages (URNAS only)
    avg_value_per_qty_urnas = 0
    urnas_total_qty = 0
    urnas_total_fat = 0
    if fat_col and quant_col and familia_col:
        urnas_data = filter_urnas_family_rows(client_data, familia_col)
        urnas_total_fat = urnas_data[fat_col].sum() if not urnas_data.empty else 0
        urnas_total_qty = urnas_data[quant_col].sum() if not urnas_data.empty else 0
        avg_value_per_qty_urnas = (urnas_total_fat / urnas_total_qty) if urnas_total_qty else 0

    # Overall average value per unit using urnas quantity
    avg_value_per_qty_total = (total_fat / urnas_total_qty) if urnas_total_qty else 0
    
    # By product with year-over-year comparison
    by_product = []
    if referencia_col and fat_col and quant_col and familia_col:
        # Current year data
        current_year_data = client_data.copy()
        
        # Previous year data
        prev_year = str(int(year_filter) - 1) if year_filter != 'all' and year_filter.isdigit() else None
        prev_year_client_data = df[(df[cliente_col] == cliente_name) & (df['__year'] == prev_year)] if prev_year else pd.DataFrame()
        
        # Group current year
        grouped_current = (
            current_year_data.groupby([referencia_col, familia_col])
            .agg({
                fat_col: 'sum',
                quant_col: 'sum'
            })
            .reset_index()
            .rename(columns={fat_col: 'fat_current', quant_col: 'qty_current'})
        )
        
        # Group previous year
        if not prev_year_client_data.empty:
            grouped_prev = (
                prev_year_client_data.groupby([referencia_col, familia_col])
                .agg({
                    fat_col: 'sum',
                    quant_col: 'sum'
                })
                .reset_index()
                .rename(columns={fat_col: 'fat_prev', quant_col: 'qty_prev'})
            )
            # Merge current and previous
            grouped = pd.merge(grouped_current, grouped_prev, on=[referencia_col, familia_col], how='left')
            grouped['fat_prev'] = grouped['fat_prev'].fillna(0)
            grouped['qty_prev'] = grouped['qty_prev'].fillna(0)
        else:
            grouped = grouped_current.copy()
            grouped['fat_prev'] = 0
            grouped['qty_prev'] = 0
        
        grouped['fat_change_pct'] = grouped.apply(
            lambda r: ((r['fat_current'] - r['fat_prev']) / r['fat_prev'] * 100) if r['fat_prev'] else None,
            axis=1
        )
        grouped['qty_change_pct'] = grouped.apply(
            lambda r: ((r['qty_current'] - r['qty_prev']) / r['qty_prev'] * 100) if r['qty_prev'] else None,
            axis=1
        )
        
        # Create sort key: urnas first (0), others (1)
        grouped['__sort_key'] = grouped[familia_col].astype(str).str.strip().str.lower().apply(
            lambda x: 0 if x in ('urna', 'urnas') else 1
        )
        # Sort by familia (urnas first), then by current revenue descending
        by_product = (
            grouped.sort_values(by=['__sort_key', 'fat_current'], ascending=[True, False])
            [[referencia_col, 'fat_current', 'qty_current', 'fat_prev', 'qty_prev', 'fat_change_pct', 'qty_change_pct']]
            .values.tolist()
        )
    
    # By month with year-over-year comparison
    by_month = []
    if mes_col and fat_col:
        # Current year monthly data (by month number)
        current_monthly = (
            client_data.groupby('__month')[fat_col]
            .sum()
            .reset_index()
            .rename(columns={fat_col: 'fat_current'})
        )
        
        # Previous year monthly data (by month number)
        if prev_year and not prev_year_client_data.empty:
            prev_monthly = (
                prev_year_client_data.groupby('__month')[fat_col]
                .sum()
                .reset_index()
                .rename(columns={fat_col: 'fat_prev'})
            )
            # Merge current and previous on month number
            monthly = pd.merge(current_monthly, prev_monthly, on='__month', how='left')
            monthly['fat_prev'] = monthly['fat_prev'].fillna(0)
        else:
            monthly = current_monthly.copy()
            monthly['fat_prev'] = 0
        
        # Calculate change
        monthly['fat_change'] = monthly['fat_current'] - monthly['fat_prev']
        monthly['fat_change_pct'] = ((monthly['fat_current'] - monthly['fat_prev']) / monthly['fat_prev'] * 100).replace([float('inf'), -float('inf')], 0).fillna(0)
        
        # Sort by month number (descending) and take last 12
        by_month = (
            monthly.sort_values(by='__month', ascending=False)
            .head(12)
            [['__month', 'fat_current', 'fat_prev', 'fat_change', 'fat_change_pct']]
            .values.tolist()
        )
    
    # Get current timestamp
    report_timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    # Prepare YoY comparison section
    if prev_year and not prev_year_client_data.empty:
        yoy_section = f"""
        <div class="card">
            <h2>📉 Year-over-Year Comparison (vs {prev_year})</h2>
            <table>
                <tr><th>Metric</th><th>{year_filter}</th><th>{prev_year}</th><th>Change</th><th>%</th></tr>
                <tr>
                    <td><strong>Total Faturação</strong></td>
                    <td>€{total_fat:,.2f}</td>
                    <td>€{prev_year_client_data[fat_col].sum() if fat_col else 0:,.2f}</td>
                    <td>€{total_fat - (prev_year_client_data[fat_col].sum() if fat_col else 0):,.2f}</td>
                    <td>{((total_fat - (prev_year_client_data[fat_col].sum() if fat_col else 0)) / (prev_year_client_data[fat_col].sum() if fat_col else 1) * 100):.1f}%</td>
                </tr>
            </table>
        </div>
        """
    else:
        yoy_section = """
        <div class="card">
            <h2>📉 Year-over-Year Comparison</h2>
            <p style="color: #666;">No data available for the previous year.</p>
        </div>
        """
    
    html = f"""
    <!DOCTYPE html>
    <html>
    <head>
        <title>Client: {cliente_name}</title>
        <style>
            * {{ margin: 0; padding: 0; box-sizing: border-box; }}
            body {{ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; padding: 20px; background: #f5f5f5; }}
            
            .header {{ 
                background: white; 
                padding: 20px; 
                margin-bottom: 20px; 
                border-radius: 8px; 
                box-shadow: 0 2px 4px rgba(0,0,0,0.1);
                display: flex;
                justify-content: space-between;
                align-items: center;
                border-top: 4px solid #667eea;
            }}
            
            .header-left {{ display: flex; align-items: center; gap: 15px; }}
            .logo-placeholder {{ 
                width: 60px; 
                height: 60px; 
                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                border-radius: 8px;
                display: flex;
                align-items: center;
                justify-content: center;
                color: white;
                font-weight: bold;
                font-size: 24px;
            }}
            
            .header-info h1 {{ color: #333; font-size: 24px; margin-bottom: 5px; }}
            .header-info p {{ color: #888; font-size: 14px; }}
            
            .header-right {{ text-align: right; }}
            .timestamp {{ color: #666; font-size: 13px; margin-bottom: 10px; }}
            
            .button-group {{ display: flex; gap: 10px; }}
            .btn {{ 
                padding: 10px 16px; 
                border: none; 
                border-radius: 6px; 
                font-size: 14px; 
                cursor: pointer; 
                font-weight: 600;
                transition: all 0.3s ease;
                text-decoration: none;
                display: inline-flex;
                align-items: center;
                gap: 6px;
            }}
            
            .btn-print {{ 
                background: #667eea; 
                color: white;
            }}
            .btn-print:hover {{ background: #5568d3; }}
            
            .btn-download {{ 
                background: #10b981; 
                color: white;
            }}
            .btn-download:hover {{ background: #059669; }}
            
            .btn-back {{ 
                background: #e5e7eb; 
                color: #333;
            }}
            .btn-back:hover {{ background: #d1d5db; }}
            
            .card {{ background: white; padding: 20px; margin: 10px 0; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }}
            .grid {{ display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 16px; }}
            h2 {{ color: #333; font-size: 18px; margin-bottom: 10px; }}
            .number {{ font-size: 28px; font-weight: bold; color: #667eea; }}
            .label {{ color: #888; font-size: 14px; text-transform: uppercase; margin-bottom: 8px; }}
            table {{ width: 100%; border-collapse: collapse; }}
            th, td {{ padding: 12px; text-align: left; border-bottom: 1px solid #ddd; }}
            th {{ background: #667eea; color: white; }}
            
            @media print {{
                body {{ background: white; padding: 0; }}
                .header {{ border: 1px solid #ddd; margin-bottom: 15px; }}
                .button-group {{ display: none; }}
                .card {{ page-break-inside: avoid; }}
            }}
        </style>
    </head>
    <body>
        <div class="header">
            <div class="header-left">
                <img src="/static/logo.png" alt="Globale RC" class="logo" style="height: 50px; object-fit: contain;">
            </div>
            <div class="header-right">
                <div class="timestamp">Generated: {report_timestamp}</div>
                <div class="comercial-info" style="font-size: 13px; color: #666; margin-bottom: 10px;">Commercial: <strong>{comercial_name}</strong></div>
                <div style="font-size: 13px; color: #666; margin-bottom: 10px;">
                    <strong>📊 Data Origin:</strong> Year: <strong>{year_filter if year_filter != 'all' else 'All Years'}</strong>
                    {f" | Month: <strong>{month_filter}</strong>" if month_filter != 'all' else ''}
                    {f" | Zona: <strong>{zona_filter}</strong>" if zona_filter != 'all' else ''}
                    {f" | Familia: <strong>{familia_filter}</strong>" if familia_filter != 'all' else ''}
                    {f" | Comercial: <strong>{comercial_filter}</strong>" if comercial_filter != 'all' else ''}
                </div>
                <div class="button-group">
                    <button class="btn btn-print" onclick="window.print()">🖨️ Print</button>
                    {f'<a href="/zona-clients?zona={zona_filter}&year={year_filter}&month={month_filter}&comercial={comercial_filter}&familia={familia_filter}" class="btn btn-back">← Back to Zona</a>' if zona_filter != 'all' else ''}
                    <a href="/dashboard" class="btn btn-back">← Dashboard</a>
                </div>
            </div>
        </div>
        
        <h2 style="margin-bottom: 20px; color: #333;">📋 Client Details: {cliente_name}</h2>
        
        <div class="grid">
            <div class="card">
                <div class="label">Client Terms</div>
                <div style="margin: 10px 0;">
                    <p style="margin: 8px 0;"><strong>Discount:</strong> {(client_data[desconto_col].iloc[0] if desconto_col and len(client_data) > 0 and pd.notna(client_data[desconto_col].iloc[0]) else 'Not defined')}</p>
                    <p style="margin: 8px 0;"><strong>Payment Terms (Days):</strong> {(int(float(str(client_data[prazo_col].iloc[0]).replace(',', '.'))) if prazo_col and len(client_data) > 0 and pd.notna(client_data[prazo_col].iloc[0]) else 'Not defined')} days</p>
                </div>
            </div>
            
            <div class="card">
                <div class="label">Total Performance</div>
                <div class="number">€ {total_fat:,.2f}</div>
            </div>

            <div class="card">
                <div class="label">Urnas Summary</div>
                <div class="number">{urnas_total_qty:,.0f}</div>
                <p>Total Urnas Quantity Sold</p>
                <div style="height:8px;"></div>
                <div class="number">€ {urnas_total_fat:,.2f}</div>
                <p>Total Value (Urnas + Estofo)</p>
                <div style="height:8px;"></div>
                <div class="number">€ {avg_value_per_qty_urnas:,.2f}</div>
                <p>Average Value per Urna Unit</p>
                <div style="height:12px;"></div>
                <div class="number">€ {total_fat:,.2f}</div>
                <p>Total Value (All Families)</p>
                <div style="height:8px;"></div>
                <div class="number">€ {avg_value_per_qty_total:,.2f}</div>
                <p>Average Value per Unit (All Families)</p>
            </div>
        </div>
        
        <div class="card">
            <div class="label">Products Purchased</div>
            <table>
                <tr>
                    <th>Referência</th>
                    <th>Faturação</th>
                    <th>YoY Change</th>
                    <th>Quantidade</th>
                    <th>YoY Change</th>
                </tr>
                {''.join([f'''<tr>
                    <td>{r}</td>
                    <td>€{f_curr:,.2f}</td>
                    <td style="color: {'green' if (f_pct is not None and f_pct > 2) else ('red' if (f_pct is not None and f_pct < -2) else 'gray')};">
                        {('↑' if (f_pct is not None and f_pct > 2) else ('↓' if (f_pct is not None and f_pct < -2) else '→')) if f_pct is not None else '-'}
                        {f" {f_pct:+.1f}%" if f_pct is not None else ''}
                    </td>
                    <td>{int(q_curr):,}</td>
                    <td style="color: {'green' if (q_pct is not None and q_pct > 2) else ('red' if (q_pct is not None and q_pct < -2) else 'gray')};">
                        {('↑' if (q_pct is not None and q_pct > 2) else ('↓' if (q_pct is not None and q_pct < -2) else '→')) if q_pct is not None else '-'}
                        {f" {q_pct:+.1f}%" if q_pct is not None else ''}
                    </td>
                </tr>''' for r, f_curr, q_curr, f_prev, q_prev, f_pct, q_pct in by_product])}
            </table>
        </div>
        
        <div class="card">
            <div class="label">Monthly Purchases (Last 12)</div>
            <table>
                <tr>
                    <th>Month</th>
                    <th>Faturação</th>
                    <th>YoY Value Change</th>
                    <th>YoY % Change</th>
                </tr>
                {''.join([f'''<tr>
                    <td>{m}</td>
                    <td>€{f_curr:,.2f}</td>
                    <td style="color: {'green' if change > 0 else ('red' if change < 0 else 'gray')};">
                        {f"€{change:+,.2f}" if f_prev > 0 else '-'}
                    </td>
                    <td style="color: {'green' if pct > 2 else ('red' if pct < -2 else 'gray')};">
                        {('↑' if pct > 2 else ('↓' if pct < -2 else '→')) if f_prev > 0 else '-'}
                        {f" {pct:+.1f}%" if f_prev > 0 else ''}
                    </td>
                </tr>''' for m, f_curr, f_prev, change, pct in by_month])}
            </table>
        </div>
        
        {generate_visit_reports_section(cliente_name, comercial_name)}
        
        <p><a href="/dashboard">← Voltar ao Dashboard</a></p>
    </body>
    </html>
    """
    return html

@app.route('/client-intelligence')
@login_required
def client_intelligence():
    """
    Client Intelligence Panel: Revenue analysis, product mix, purchase frequency, and recommendations.
    Shows strategic overview for commercial agents preparing client visits.
    """
    from markupsafe import Markup
    
    cliente_name = request.args.get('cliente')
    if not cliente_name:
        return redirect(url_for('dashboard'))
    
    # Load data
    df = fetch_data()
    if df is None:
        return "Error loading data", 500
    
    def find_col(*keywords):
        for col in df.columns:
            name = col.lower()
            if all(k in name for k in keywords):
                return col
        return None
    
    # Access control: ensure comercial user can only access their assigned clients
    user_email = normalize_email(session.get('user_email'))
    user_role = get_user_role(user_email)
    
    if user_role == 'comercial' and user_email in SALES_ACCESS_MAP:
        assigned_comerciais = get_user_comercials(user_email)
        allowed = [a.strip().lower() for a in assigned_comerciais]
        
        # Check if this client belongs to any assigned comercial
        cliente_col = find_col('cliente')
        comercial_col = find_col('comercial')
        
        if cliente_col and comercial_col:
            client_data = df[df[cliente_col] == cliente_name]
            if not client_data.empty:
                comercials = client_data[comercial_col].astype(str).str.strip().str.lower().unique()
                if not any(c in allowed for c in comercials):
                    return "Acesso negado", 403
    
    # Try to load visit logs if they exist
    visit_logs_df = None
    try:
        creds = get_google_credentials()
        if creds:
            gc = gspread.authorize(creds)
            spreadsheet_id = session.get('spreadsheet_id') or DEFAULT_SPREADSHEET_ID
            spreadsheet = gc.open_by_key(spreadsheet_id)
            
            # Try to find a visits/reports sheet (common names)
            for ws in spreadsheet.worksheets():
                if any(name in ws.title.lower() for name in ['visit', 'visita', 'report', 'relatório']):
                    all_values = ws.get_all_values()
                    if len(all_values) > 1:
                        visit_logs_df = pd.DataFrame(all_values[1:], columns=all_values[0])
                    break
    except:
        visit_logs_df = None
    
    # Generate intelligence profile
    profile = cih.generate_client_intelligence_profile(df, cliente_name, visit_logs_df)
    
    if not profile.get('available', False):
        return render_template('client_intelligence.html', profile=profile)
    
    return render_template('client_intelligence.html', profile=profile)

@app.route('/annual-report')
@login_required
def annual_report():
    """Generate comprehensive annual report with annual, semestral, and trimestral breakdowns."""
    user_email = session.get('user_email')
    user_role = get_user_role(user_email)
    scope = request.args.get('scope', 'all')
    
    # Comercials can only view personal scope, others can view all
    if user_role == 'comercial' and scope != 'personal':
        return redirect(url_for('dashboard'))
    if user_role is None:
        return redirect(url_for('login'))

    year_param = request.args.get('year', '2025')

    
    df = fetch_data()
    if df is None:
        return "Error loading data", 500
    
    def find_col(*keywords):
        for col in df.columns:
            name = col.lower()
            if all(k in name for k in keywords):
                return col
        return None
    
    # Parse dates
    mes_col = find_col('mês') or find_col('mes')
    referencia_col = find_col('referencia')
    fat_col = find_col('fatura')
    quant_col = find_col('quant')
    cliente_col = find_col('cliente')
    comercial_col = find_col('comercial')
    familia_col = find_col('familia')
    zona_col = find_col('zona')
    
    if mes_col:
        def parse_period(value):
            if value is None:
                return (None, None)
            s = str(value).strip()
            if not s:
                return (None, None)
            s = s.replace('-', '/').replace('.', '/')
            m = re.search(r"(\d{4})\D?(\d{1,2})", s)
            if m:
                year = m.group(1)
                month = m.group(2).zfill(2)
                return (year, month)
            m = re.search(r"(\d{1,2})\D?(\d{4})", s)
            if m:
                month = m.group(1).zfill(2)
                year = m.group(2)
                return (year, month)
            return (None, None)
        
        ym = df[mes_col].apply(parse_period)
        df['__year'] = ym.apply(lambda x: x[0])
        df['__month'] = ym.apply(lambda x: x[1])
    else:
        df['__year'] = None
        df['__month'] = None
    
    # Apply access control for personal scope
    if user_role == 'comercial':
        comercial_col = find_col('comercial')
        if comercial_col:
            assigned = get_user_comercials(user_email)
            allowed = [a.strip().lower() for a in assigned]
            df = df[df[comercial_col].astype(str).str.lower().isin(allowed)]

    # Filter by year
    year_data = df[df['__year'] == year_param]
    if year_data.empty:
        return f"<html><body><h1>No data for year: {year_param}</h1><p><a href='/dashboard'>← Back</a></p></body></html>"
    
    # Get available years
    years = sorted(df['__year'].dropna().unique().tolist())
    
    # Helper to format period data
    def get_period_stats(data, label):
        # CRITICAL: Filter for URNAS only before counting quantities
        urnas_data = filter_urnas_family_rows(data.copy(), familia_col) if familia_col else data
        
        total_fat = data[fat_col].sum() if fat_col else 0
        total_quant = urnas_data[quant_col].sum() if quant_col and not urnas_data.empty else 0
        num_clients = data[cliente_col].nunique() if cliente_col else 0
        num_products = data[referencia_col].nunique() if referencia_col else 0
        
        # Debug logging
        print(f"[ANNUAL REPORT] {label}: Total revenue=€{total_fat:.2f}, Urnas quantity={int(total_quant):,} (filtered from {len(data)} to {len(urnas_data)} rows)")
        
        return {
            'label': label,
            'revenue': total_fat,
            'quantity': total_quant,
            'clients': num_clients,
            'products': num_products
        }
    
    # Annual stats
    annual_stats = get_period_stats(year_data, f'Year {year_param}')
    prev_year = str(int(year_param) - 1) if year_param.isdigit() else None
    prev_year_data = df[df['__year'] == prev_year] if prev_year else pd.DataFrame()
    prev_annual_stats = get_period_stats(prev_year_data, f'Year {prev_year}') if not prev_year_data.empty else None

    def build_yoy_row(label, current, previous, value_type):
        if previous is None or previous == 0:
            return {
                'label': label,
                'current': current,
                'previous': previous,
                'change': None,
                'pct': None,
                'color': '#6b7280',
                'arrow': '-'
            }
        change = current - previous
        pct = (change / previous) * 100
        if pct > 2:
            color = 'green'
            arrow = '↑'
        elif pct < -2:
            color = 'red'
            arrow = '↓'
        else:
            color = 'gray'
            arrow = '→'
        return {
            'label': label,
            'current': current,
            'previous': previous,
            'change': change,
            'pct': pct,
            'color': color,
            'arrow': arrow
        }

    def format_value(label, value, is_change=False):
        if value is None:
            return '-'
        if label == 'Revenue':
            return f"€{value:+,.2f}" if is_change else f"€ {value:,.2f}"
        return f"{int(value):+,.0f}" if is_change else f"{int(value):,}"

    yoy_rows = []
    if prev_annual_stats:
        raw_rows = [
            build_yoy_row('Receita', annual_stats['revenue'], prev_annual_stats['revenue'], 'currency'),
            build_yoy_row('Urnas', annual_stats['quantity'], prev_annual_stats['quantity'], 'int'),
            build_yoy_row('Clientes', annual_stats['clients'], prev_annual_stats['clients'], 'int'),
            build_yoy_row('Famílias', annual_stats['products'], prev_annual_stats['products'], 'int')
        ]
        yoy_rows = [
            {
                **r,
                'current_fmt': format_value(r['label'], r['current']),
                'previous_fmt': format_value(r['label'], r['previous']),
                'change_fmt': format_value(r['label'], r['change'], True),
                'pct_fmt': f"{r['pct']:+.1f}%" if r['pct'] is not None else '-'
            }
            for r in raw_rows
        ]
    
    # Semestral (6-month) stats - S1: 01-06, S2: 07-12
    sem1_data = year_data[year_data['__month'].isin(['01','02','03','04','05','06'])]
    sem2_data = year_data[year_data['__month'].isin(['07','08','09','10','11','12'])]
    semestral_stats = [
        get_period_stats(sem1_data, f'Semester 1 (Jan-Jun)'),
        get_period_stats(sem2_data, f'Semester 2 (Jul-Dec)')
    ]
    
    # Trimestral (3-month) stats - Q1, Q2, Q3, Q4
    q1_data = year_data[year_data['__month'].isin(['01','02','03'])]
    q2_data = year_data[year_data['__month'].isin(['04','05','06'])]
    q3_data = year_data[year_data['__month'].isin(['07','08','09'])]
    q4_data = year_data[year_data['__month'].isin(['10','11','12'])]
    trimestral_stats = [
        get_period_stats(q1_data, f'Quarter 1 (Jan-Mar)'),
        get_period_stats(q2_data, f'Quarter 2 (Apr-Jun)'),
        get_period_stats(q3_data, f'Quarter 3 (Jul-Sep)'),
        get_period_stats(q4_data, f'Quarter 4 (Oct-Dec)')
    ]
    
    # Top clients
    top_clients = []
    if cliente_col and fat_col:
        top_clients = (
            year_data.groupby(cliente_col)[fat_col]
            .sum()
            .nlargest(10)
            .reset_index()
            .values.tolist()
        )
    
    # Top comercials
    top_comercials = []
    if comercial_col and fat_col:
        top_comercials = (
            year_data.groupby(comercial_col)[fat_col]
            .sum()
            .nlargest(10)
            .reset_index()
            .values.tolist()
        )
    
    # Top families
    top_familias = []
    if familia_col and fat_col:
        top_familias = (
            year_data.groupby(familia_col)[fat_col]
            .sum()
            .nlargest(10)
            .reset_index()
            .values.tolist()
        )
    
    # Top zones
    top_zones = []
    if zona_col and fat_col:
        top_zones = (
            year_data.groupby(zona_col)[fat_col]
            .sum()
            .nlargest(10)
            .reset_index()
            .values.tolist()
        )
    
    from datetime import datetime
    report_timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    report_title = f"Relatório Anual {year_param}" + (" (Meus Dados)" if user_role == 'comercial' else "")
    report_subtitle = "Análise Completa de Vendas" + (" - Âmbito Pessoal" if user_role == 'comercial' else "")

    yoy_section = (
        f"""
        <div class=\"card\">
            <h2>📉 Year-over-Year Comparison (vs {prev_year})</h2>
            <table>
                <tr><th>Metric</th><th>{year_param}</th><th>{prev_year}</th><th>Change</th><th>%</th></tr>
                {''.join([f'<tr><td>{r["label"]}</td><td>{r["current_fmt"]}</td><td>{r["previous_fmt"]}</td><td>{r["change_fmt"]}</td><td style="color: {r["color"]};">{r["arrow"]} {r["pct_fmt"]}</td></tr>' for r in yoy_rows])}
            </table>
        </div>
        """
        if prev_annual_stats else
        """
        <div class=\"card\">
            <h2>📉 Year-over-Year Comparison</h2>
            <p style=\"color: #666;\">No data available for the previous year.</p>
        </div>
        """
    )
    
    html = f"""
    <!DOCTYPE html>
    <html>
    <head>
        <title>Relatório Anual {year_param}</title>
        <meta charset="UTF-8">
        <style>
            @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');
            
            * {{ margin: 0; padding: 0; box-sizing: border-box; }}
            html {{ scroll-behavior: smooth; }}
            body {{ 
                font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; 
                padding: 0;
                background: linear-gradient(135deg, #f5f7fa 0%, #eef2f5 100%);
                min-height: 100vh;
                color: #3d4557;
            }}
            
            .header {{ 
                background: linear-gradient(135deg, #ffffff 0%, #f9fbfd 100%);
                padding: 20px 40px;
                display: flex;
                align-items: center;
                justify-content: space-between;
                border-bottom: 1px solid rgba(100, 140, 200, 0.12);
                box-shadow: 0 2px 12px rgba(100, 140, 200, 0.08);
            }}
            
            .header-left {{ display: flex; align-items: center; gap: 20px; }}
            .header-left img {{ height: 50px; object-fit: contain; }}
            .header-info h1 {{ color: #2d3a4d; font-size: 28px; margin-bottom: 5px; font-weight: 700; }}
            .header-info p {{ color: #6b7684; font-size: 14px; font-weight: 500; }}
            
            .header-right {{ text-align: right; }}
            .timestamp {{ color: #6b7684; font-size: 13px; margin-bottom: 10px; font-weight: 500; }}
            
            .button-group {{ display: flex; gap: 10px; }}
            .btn {{ 
                padding: 10px 16px; 
                border: none; 
                border-radius: 6px; 
                font-size: 14px; 
                cursor: pointer; 
                font-weight: 600;
                transition: all 0.3s ease;
                text-decoration: none;
                display: inline-flex;
                align-items: center;
                gap: 6px;
            }}
            
            .btn-print {{ background: linear-gradient(135deg, rgba(100, 140, 200, 0.2), rgba(100, 140, 200, 0.08)); color: #4a5f8f; border: 1px solid rgba(100, 140, 200, 0.2); }}
            .btn-print:hover {{ background: linear-gradient(135deg, rgba(100, 140, 200, 0.3), rgba(100, 140, 200, 0.12)); border-color: rgba(100, 140, 200, 0.4); }}
            .btn-back {{ background: rgba(100, 140, 200, 0.08); color: #4a5f8f; border: 1px solid rgba(100, 140, 200, 0.15); }}
            .btn-back:hover {{ background: rgba(100, 140, 200, 0.12); border-color: rgba(100, 140, 200, 0.25); }}
            
            .container {{ max-width: 1600px; margin: 0 auto; padding: 40px; }}
            .card {{ background: linear-gradient(135deg, rgba(255, 255, 255, 0.8) 0%, rgba(249, 251, 253, 0.8) 100%); padding: 32px; margin: 20px 0; border-radius: 10px; border: 1px solid rgba(100, 140, 200, 0.12); backdrop-filter: blur(5px); box-shadow: 0 4px 16px rgba(100, 140, 200, 0.06); }}
            .grid {{ display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; }}
            .stat-box {{ background: linear-gradient(135deg, rgba(100, 140, 200, 0.15), rgba(100, 140, 200, 0.05)); color: #4a5f8f; padding: 24px; border-radius: 10px; border: 1px solid rgba(100, 140, 200, 0.2); }}
            .stat-value {{ font-size: 32px; font-weight: 800; margin: 12px 0; color: #4a5f8f; }}
            .stat-label {{ font-size: 12px; opacity: 0.75; text-transform: uppercase; letter-spacing: 0.5px; font-weight: 600; color: #6b7684; }}
            
            h2 {{ color: #2d3a4d; margin: 20px 0 20px 0; font-size: 18px; border-bottom: 2px solid rgba(100, 140, 200, 0.25); padding-bottom: 12px; font-weight: 700; }}
            
            table {{ width: 100%; border-collapse: collapse; }}
            th, td {{ padding: 14px; text-align: left; border-bottom: 1px solid rgba(100, 140, 200, 0.1); }}
            th {{ background: rgba(100, 140, 200, 0.08); color: #2d3a4d; font-weight: 700; font-size: 12px; text-transform: uppercase; letter-spacing: 0.5px; }}
            td {{ color: #5a6575; font-weight: 500; }}
            tr:hover {{ background: rgba(100, 140, 200, 0.04); }}
            td:last-child {{ text-align: right; color: #4a5f8f; font-weight: 600; }}
            
            .period-grid {{ display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 16px; }}
            .period-card {{ background: linear-gradient(135deg, rgba(255, 255, 255, 0.8) 0%, rgba(249, 251, 253, 0.8) 100%); padding: 20px; border-radius: 10px; border: 1px solid rgba(100, 140, 200, 0.12); }}
            .period-label {{ font-weight: 700; color: #2d3a4d; margin-bottom: 15px; }}
            .period-stat {{ display: flex; justify-content: space-between; margin: 10px 0; font-size: 14px; }}
            .period-stat-value {{ color: #4a5f8f; font-weight: 600; }}
            
            @media print {{
                body {{ background: white; padding: 0; }}
                .header {{ border-bottom: 1px solid #ddd; margin-bottom: 20px; }}
                .button-group {{ display: none; }}
                .card {{ page-break-inside: avoid; }}
            }}
        </style>
    </head>
    <body>
        <div class="header">
            <div class="header-left">
                <img src="/static/logo.png" alt="Globale RC" style="height: 50px; object-fit: contain;">
                <div class="header-info">
                    <h1>{report_title}</h1>
                    <p>{report_subtitle}</p>
                </div>
            </div>
            <div class="header-right">
                <div class="timestamp">Generated: {report_timestamp}</div>
                <div class="button-group">
                    <button class="btn btn-print" onclick="window.print()">🖨️ Print</button>
                    <a href="/dashboard" class="btn btn-back">← Dashboard</a>
                </div>
            </div>
        </div>
        
        <div class="container">
        <div class="card">
            <h2>📊 Resumo Anual - {year_param}</h2>
            <div class="grid">
                <div class="stat-box">
                    <div class="stat-label">Receita Total</div>
                    <div class="stat-value">€ {annual_stats['revenue']:,.2f}</div>
                </div>
                <div class="stat-box">
                    <div class="stat-label">Urnas Vendidas</div>
                    <div class="stat-value">{int(annual_stats['quantity']):,}</div>
                </div>
                <div class="stat-box">
                    <div class="stat-label">Clientes Únicos</div>
                    <div class="stat-value">{annual_stats['clients']}</div>
                </div>
                <div class="stat-box">
                    <div class="stat-label">Famílias de Produtos</div>
                    <div class="stat-value">{annual_stats['products']}</div>
                </div>
            </div>
        </div>

        {yoy_section}
        
        <div class="card">
            <h2>📈 Análise Semestral (6 Meses)</h2>
            <div class="period-grid">
                {''.join([f'''
                <div class="period-card">
                    <div class="period-label">{s['label']}</div>
                    <div class="period-stat">
                        <span>Receita:</span>
                        <span class="period-stat-value">€ {s['revenue']:,.2f}</span>
                    </div>
                    <div class="period-stat">
                        <span>Urnas:</span>
                        <span class="period-stat-value">{int(s['quantity']):,}</span>
                    </div>
                    <div class="period-stat">
                        <span>Clientes:</span>
                        <span class="period-stat-value">{s['clients']}</span>
                    </div>
                </div>
                ''' for s in semestral_stats])}
            </div>
        </div>
        
        <div class="card">
            <h2>📊 Análise Trimestral (3 Meses)</h2>
            <div class="period-grid">
                {''.join([f'''
                <div class="period-card">
                    <div class="period-label">{t['label']}</div>
                    <div class="period-stat">
                        <span>Receita:</span>
                        <span class="period-stat-value">€ {t['revenue']:,.2f}</span>
                    </div>
                    <div class="period-stat">
                        <span>Urnas:</span>
                        <span class="period-stat-value">{int(t['quantity']):,}</span>
                    </div>
                    <div class="period-stat">
                        <span>Clientes:</span>
                        <span class="period-stat-value">{t['clients']}</span>
                    </div>
                </div>
                ''' for t in trimestral_stats])}
            </div>
        </div>
        
        <div class="card">
            <h2>👥 Top 10 Clientes</h2>
            <table>
                <tr><th>Cliente</th><th>Receita</th></tr>
                {''.join([f'<tr><td>{c}</td><td>€{f:,.2f}</td></tr>' for c, f in top_clients])}
            </table>
        </div>
        
        <div class="card">
            <h2>💼 Top 10 Comerciais</h2>
            <table>
                <tr><th>Comercial</th><th>Receita</th></tr>
                {''.join([f'<tr><td>{c}</td><td>€{f:,.2f}</td></tr>' for c, f in top_comercials])}
            </table>
        </div>
        
        <div class="card">
            <h2>📦 Top 10 Famílias de Produtos</h2>
            <table>
                <tr><th>Family</th><th>Revenue</th></tr>
                {''.join([f'<tr><td>{f}</td><td>€{r:,.2f}</td></tr>' for f, r in top_familias])}
            </table>
        </div>
        
        <div class="card">
            <h2>🗺️ Top 10 Zones</h2>
            <table>
                <tr><th>Zone</th><th>Revenue</th></tr>
                {''.join([f'<tr><td>{z}</td><td>€{r:,.2f}</td></tr>' for z, r in top_zones])}
            </table>
        </div>
        
        <p style="text-align: center; margin-top: 40px; color: #999; font-size: 12px;">
            Globale RC Relatório de Vendas{'' if user_role != 'comercial' else ' (Meus Dados)'} - {year_param}
        </p>
    </body>
    </html>
    """
    return html

@app.route('/clear-cache')
@login_required
def clear_cache_route():
    """Clear all cached data to force fresh fetch from Google Sheets"""
    user_email = session.get('user_email')
    if not has_permission(user_email, 'edit_data'):
        return "Access denied. Admin only.", 403
    
    clear_cache()
    return """
    <!DOCTYPE html>
    <html>
    <head>
        <title>Cache Cleared</title>
        <style>
            body { font-family: Arial; padding: 40px; text-align: center; background: #f5f5f5; }
            .container { background: white; padding: 40px; border-radius: 8px; max-width: 500px; margin: 0 auto; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
            h1 { color: #28a745; }
            .info { color: #666; margin: 20px 0; }
            a { display: inline-block; margin-top: 20px; padding: 12px 24px; background: #667eea; color: white; text-decoration: none; border-radius: 6px; }
            a:hover { background: #5568d3; }
        </style>
    </head>
    <body>
        <div class="container">
            <h1>✓ Cache Cleared</h1>
            <p class="info">All cached data has been cleared. The next page load will fetch fresh data from Google Sheets.</p>
            <a href="/dashboard">← Back to Dashboard</a>
        </div>
    </body>
    </html>
    """

@app.route('/set-spreadsheet')
@login_required
def set_spreadsheet():
    sid = request.args.get('id')
    if sid:
        session['spreadsheet_id'] = sid
        return jsonify({'success': True})
    return jsonify({'success': False}), 400

@app.route('/data-health')
@login_required
def data_health():
    """Admin route to check data validation status and quality"""
    user_email = session.get('user_email')
    user_role = get_user_role(user_email)
    
    if user_role != 'admin':
        return "Access denied - Admin only", 403
    
    # Fetch data
    df_sales = fetch_data()
    df_objectives = fetch_objectives()
    
    if df_sales is None:
        return "Could not fetch sales data", 500
    
    try:
        # Run validation
        validator = DataValidator(df_sales, "Sales Data")
        results = validator.validate_all()
        
        # Validate objectives
        obj_issues = validate_objectives_sheet(df_objectives)
    except Exception as e:
        return f"Validation error: {str(e)}", 500
    
    # Count issues by severity
    critical_count = len(results['critical'])
    warning_count = len(results['warnings'])
    info_count = len(results['info'])
    
    # Determine overall health status
    if critical_count > 0:
        health_status = 'CRITICAL'
        health_color = '#ef4444'
        health_icon = '🚨'
        health_message = 'Critical issues detected - Immediate action required'
    elif warning_count > 0:
        health_status = 'WARNING'
        health_color = '#f59e0b'
        health_icon = '⚠️'
        health_message = 'Some issues detected - Review recommended'
    else:
        health_status = 'HEALTHY'
        health_color = '#10b981'
        health_icon = '✅'
        health_message = 'All data quality checks passed'
    
    # Build compact HTML report (truncated for brevity - full implementation similar to previous design)
    return f"""<!DOCTYPE html>
    <html>
    <head>
        <title>📊 Data Health - Sales Dashboard</title>
        <meta charset="UTF-8">
        <style>
            body {{ font-family: 'Inter', system-ui, sans-serif; background: #f5f7fa; padding: 20px; }}
            .container {{ max-width: 1200px; margin: 0 auto; }}
            .header {{ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; border-radius: 12px; margin-bottom: 20px; }}
            .health-status {{ background: white; padding: 30px; border-radius: 12px; border-left: 5px solid {health_color}; margin-bottom: 20px; }}
            .status-icon {{ font-size: 48px; }}
            .stats {{ display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 15px; margin-bottom: 20px; }}
            .stat-card {{ background: white; padding: 20px; border-radius: 10px; text-align: center; }}
            .stat-number {{ font-size: 32px; font-weight: 700; color: #667eea; }}
            .stat-label {{ font-size: 13px; color: #64748b; text-transform: uppercase; }}
            .critical {{ color: #ef4444; border-top: 4px solid #ef4444; }}
            .warning {{ color: #f59e0b; border-top: 4px solid #f59e0b; }}
            .issue-card {{ background: white; padding: 20px; margin: 15px 0; border-radius: 8px; border-left: 4px solid #ef4444; }}
            .issue-type {{ font-family: monospace; font-size: 11px; background: #f1f5f9; padding: 4px 8px; border-radius: 4px; }}
            .recommendation {{ background: #f8fafc; padding: 12px; margin-top: 10px; border-radius: 6px; }}
            .btn {{ padding: 10px 20px; background: #667eea; color: white; text-decoration: none; border-radius: 6px; display: inline-block; margin: 10px 5px 0 0; }}
        </style>
    </head>
    <body>
        <div class="container">
            <div class="header">
                <h1>📊 Data Health Check</h1>
                <p>System validation report</p>
            </div>
            <div class="health-status">
                <div class="status-icon">{health_icon}</div>
                <h2>{health_status}</h2>
                <p>{health_message}</p>
            </div>
            <div class="stats">
                <div class="stat-card critical"><div class="stat-number">{critical_count}</div><div class="stat-label">Critical</div></div>
                <div class="stat-card warning"><div class="stat-number">{warning_count}</div><div class="stat-label">Warnings</div></div>
                <div class="stat-card"><div class="stat-number">{info_count}</div><div class="stat-label">Info</div></div>
                <div class="stat-card"><div class="stat-number">{results['total_rows']:,}</div><div class="stat-label">Total Rows</div></div>
            </div>
            {''.join([f'<div class="issue-card"><span class="issue-type">{i["type"]}</span><h3>{i["message"]}</h3><div class="recommendation"><strong>Fix:</strong> {i["recommendation"]}</div></div>' for i in results['critical'][:5]])}
            {''.join([f'<div class="issue-card" style="border-left-color:#f59e0b;"><span class="issue-type">{i["type"]}</span><h3>{i["message"]}</h3><div class="recommendation">{i["recommendation"]}</div></div>' for i in results['warnings'][:5]])}
            <p style="margin-top:20px;color:#94a3b8;">Validated: {results['validated_at']}</p>
            <a href="/dashboard" class="btn">← Dashboard</a>
            <a href="/data-health" class="btn">🔄 Refresh</a>
            <a href="/debug/familia-values" class="btn" style="background: #f59e0b;">🔍 Check Familia Values</a>
        </div>
    </body>
    </html>"""

@app.route('/debug/familia-values')
@login_required
def debug_familia_values():
    """Show all unique Familia column values to help diagnose urnas filtering."""
    user_email = normalize_email(session.get('user_email'))
    user_role = get_user_role(user_email)
    
    if user_role != 'admin':
        return "Access denied - Admin only", 403
    
    df = fetch_data()
    if df is None or df.empty:
        return "No data available", 500
    
    # Find familia column
    familia_col = None
    for col in df.columns:
        if 'familia' in col.lower() or 'família' in col.lower():
            familia_col = col
            break
    
    if not familia_col:
        return "No Familia column found in sheet", 500
    
    # Get all unique values with counts
    familia_values = df[familia_col].fillna('[EMPTY]').astype(str).str.strip()
    value_counts = familia_values.value_counts().to_dict()
    
    # Build HTML report
    rows_html = ""
    for value, count in sorted(value_counts.items(), key=lambda x: -x[1]):
        value_lower = value.lower().replace(' ', ' ').strip()
        is_exact_match = value_lower in ['urna', 'urnas']
        is_urna_variant = 'urn' in value_lower and not is_exact_match
        
        if is_exact_match:
            badge_color = "#10b981"
            badge_text = "✅ EXACT MATCH"
        elif is_urna_variant:
            badge_color = "#f59e0b"
            badge_text = "⚠️ URNA VARIANT"
        else:
            badge_color = "#64748b"
            badge_text = ""
        
        rows_html += f"""
        <tr style="background: {'#f0fdf4' if is_exact_match else '#fffbeb' if is_urna_variant else 'white'};">
            <td style="font-family: monospace; font-weight: 600;">{value}</td>
            <td>{count:,}</td>
            <td style="font-family: monospace; color: #64748b;">{value_lower}</td>
            <td>{f'<span style="background: {badge_color}; color: white; padding: 4px 8px; border-radius: 4px; font-size: 11px; font-weight: 600;">{badge_text}</span>' if badge_text else ''}</td>
        </tr>
        """
    
    return f"""<!DOCTYPE html>
    <html>
    <head>
        <title>Familia Column Values - Diagnostic</title>
        <meta charset="UTF-8">
        <style>
            body {{
                font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                margin: 0;
                padding: 20px;
            }}
            .container {{
                max-width: 1000px;
                margin: 0 auto;
                background: white;
                border-radius: 12px;
                padding: 30px;
                box-shadow: 0 10px 40px rgba(0,0,0,0.2);
            }}
            h1 {{
                color: #2d3748;
                margin-bottom: 10px;
                font-size: 28px;
            }}
            .info {{
                background: #eff6ff;
                border-left: 4px solid #3b82f6;
                padding: 15px;
                margin: 20px 0;
                border-radius: 4px;
            }}
            .info strong {{ color: #1e40af; }}
            table {{
                width: 100%;
                border-collapse: collapse;
                margin-top: 20px;
            }}
            thead {{
                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                color: white;
            }}
            th {{
                padding: 12px;
                text-align: left;
                font-size: 13px;
                font-weight: 600;
                text-transform: uppercase;
                letter-spacing: 0.5px;
            }}
            td {{
                padding: 12px;
                border-bottom: 1px solid #e5e7eb;
            }}
            tr:hover {{
                background: #f9fafb !important;
            }}
            .btn {{
                display: inline-block;
                padding: 10px 20px;
                background: #667eea;
                color: white;
                text-decoration: none;
                border-radius: 6px;
                margin-top: 20px;
                font-weight: 600;
                transition: all 0.3s;
            }}
            .btn:hover {{
                background: #5568d3;
                transform: translateY(-2px);
            }}
            .legend {{
                margin: 20px 0;
                padding: 15px;
                background: #f8fafc;
                border-radius: 6px;
            }}
            .legend-item {{
                display: inline-block;
                margin-right: 20px;
                font-size: 13px;
            }}
        </style>
    </head>
    <body>
        <div class="container">
            <h1>🔍 Familia Column Values</h1>
            <p style="color: #64748b; margin-bottom: 20px;">All unique values found in the Familia column with row counts</p>
            
            <div class="info">
                <strong>Current Filter Logic:</strong> Only rows with familia = "Urna" or "Urnas" (case-insensitive, exact match) are counted as urnas.<br>
                <strong>Column Name:</strong> {familia_col}<br>
                <strong>Total Unique Values:</strong> {len(value_counts)}<br>
                <strong>Total Rows:</strong> {len(df):,}
            </div>
            
            <div class="legend">
                <div class="legend-item">
                    <span style="background: #10b981; color: white; padding: 4px 8px; border-radius: 4px; font-size: 11px; font-weight: 600;">✅ EXACT MATCH</span>
                    = Will be counted as urnas
                </div>
                <div class="legend-item">
                    <span style="background: #f59e0b; color: white; padding: 4px 8px; border-radius: 4px; font-size: 11px; font-weight: 600;">⚠️ URNA VARIANT</span>
                    = Contains "urn" but NOT counted as urnas
                </div>
            </div>
            
            <table>
                <thead>
                    <tr>
                        <th>Original Value</th>
                        <th>Row Count</th>
                        <th>Normalized (lowercase)</th>
                        <th>Filter Status</th>
                    </tr>
                </thead>
                <tbody>
                    {rows_html}
                </tbody>
            </table>
            
            <a href="/dashboard" class="btn">← Dashboard</a>
            <a href="/data-health" class="btn">🔍 Data Health</a>
        </div>
    </body>
    </html>"""

@app.route('/debug/comercial-email-mapping')
@login_required
def debug_comercial_email_mapping():
    """Debug mapping coverage between Vendas comercial names and email recipients."""
    user_email = normalize_email(session.get('user_email'))

    if user_email not in ADMIN_EMAILS:
        return f"""
        <!DOCTYPE html>
        <html>
        <head>
            <title>Acesso Negado</title>
            <meta charset="UTF-8">
            <style>
                body {{ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; }}
                .container {{ background: white; padding: 40px; border-radius: 12px; max-width: 500px; box-shadow: 0 10px 40px rgba(0,0,0,0.2); text-align: center; }}
                h1 {{ color: #e74c3c; margin-bottom: 20px; }}
                p {{ color: #666; line-height: 1.6; }}
                a {{ display: inline-block; margin-top: 20px; padding: 12px 30px; background: #667eea; color: white; text-decoration: none; border-radius: 6px; transition: all 0.3s; }}
                a:hover {{ background: #5568d3; transform: translateY(-2px); }}
            </style>
        </head>
        <body>
            <div class="container">
                <h1>🚫 Acesso Negado</h1>
                <p>Apenas administradores principais podem acessar esta ferramenta.</p>
                <a href="/dashboard">← Voltar ao Dashboard</a>
            </div>
        </body>
        </html>
        """, 403

    df = fetch_data()
    if df is None or df.empty:
        return f"""
        <!DOCTYPE html>
        <html>
        <head>
            <title>Erro</title>
            <meta charset="UTF-8">
            <style>
                body {{ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; }}
                .container {{ background: white; padding: 40px; border-radius: 12px; max-width: 500px; box-shadow: 0 10px 40px rgba(0,0,0,0.2); text-align: center; }}
                h1 {{ color: #e74c3c; margin-bottom: 20px; }}
                p {{ color: #666; line-height: 1.6; }}
                a {{ display: inline-block; margin-top: 20px; padding: 12px 30px; background: #667eea; color: white; text-decoration: none; border-radius: 6px; transition: all 0.3s; }}
                a:hover {{ background: #5568d3; transform: translateY(-2px); }}
            </style>
        </head>
        <body>
            <div class="container">
                <h1>⚠️ Erro</h1>
                <p>Sem dados de Vendas disponíveis.</p>
                <a href="/dashboard">← Voltar ao Dashboard</a>
            </div>
        </body>
        </html>
        """, 500

    comercial_col = None
    for col in df.columns:
        if 'comercial' in str(col).strip().lower():
            comercial_col = col
            break

    if not comercial_col:
        return f"""
        <!DOCTYPE html>
        <html>
        <head>
            <title>Erro</title>
            <meta charset="UTF-8">
            <style>
                body {{ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; }}
                .container {{ background: white; padding: 40px; border-radius: 12px; max-width: 500px; box-shadow: 0 10px 40px rgba(0,0,0,0.2); text-align: center; }}
                h1 {{ color: #e74c3c; margin-bottom: 20px; }}
                p {{ color: #666; line-height: 1.6; }}
                a {{ display: inline-block; margin-top: 20px; padding: 12px 30px; background: #667eea; color: white; text-decoration: none; border-radius: 6px; transition: all 0.3s; }}
                a:hover {{ background: #5568d3; transform: translateY(-2px); }}
            </style>
        </head>
        <body>
            <div class="container">
                <h1>⚠️ Erro</h1>
                <p>Coluna de comercial não encontrada em Vendas.</p>
                <a href="/dashboard">← Voltar ao Dashboard</a>
            </div>
        </body>
        </html>
        """, 500

    comercial_names = sorted([
        str(name).strip()
        for name in df[comercial_col].dropna().unique().tolist()
        if str(name).strip()
    ])

    mapped = []
    missing = []

    for comercial_name in comercial_names:
        email = get_comercial_email_from_name(comercial_name)
        if email:
            mapped.append({'comercial': comercial_name, 'email': email})
        else:
            missing.append(comercial_name)

    # Build HTML table rows for mapped comercials
    mapped_rows = ''.join([
        f'<tr><td style="padding: 12px; border-bottom: 1px solid #ecf0f1;"><strong>{item["comercial"]}</strong></td><td style="padding: 12px; border-bottom: 1px solid #ecf0f1; color: #27ae60;">✓ {item["email"]}</td></tr>'
        for item in mapped
    ]) if mapped else '<tr><td colspan="2" style="padding: 12px; text-align: center; color: #95a5a6;">Nenhum comercial mapeado</td></tr>'

    # Build HTML list items for missing comercials
    missing_items = ''.join([
        f'<li style="padding: 8px; background: #fff3cd; margin: 5px 0; border-radius: 4px; border-left: 4px solid #ffc107;">{name}</li>'
        for name in missing
    ]) if missing else '<li style="padding: 8px; color: #95a5a6;">Todos os comerciais estão mapeados! 🎉</li>'

    return f"""
    <!DOCTYPE html>
    <html>
    <head>
        <title>Mapeamento Comercial ↔ Email</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            * {{ margin: 0; padding: 0; box-sizing: border-box; }}
            body {{
                font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                padding: 30px;
                min-height: 100vh;
            }}
            .container {{
                max-width: 1000px;
                margin: 0 auto;
                background: white;
                border-radius: 16px;
                box-shadow: 0 20px 60px rgba(0,0,0,0.3);
                overflow: hidden;
            }}
            .header {{
                background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                color: white;
                padding: 40px;
                text-align: center;
            }}
            .header h1 {{
                font-size: 32px;
                margin-bottom: 10px;
                font-weight: 600;
            }}
            .header p {{
                opacity: 0.9;
                font-size: 16px;
            }}
            .stats {{
                display: grid;
                grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
                gap: 20px;
                padding: 30px;
                background: #f8f9fa;
            }}
            .stat-card {{
                background: white;
                padding: 20px;
                border-radius: 12px;
                box-shadow: 0 2px 8px rgba(0,0,0,0.1);
                text-align: center;
            }}
            .stat-number {{
                font-size: 36px;
                font-weight: bold;
                margin-bottom: 5px;
            }}
            .stat-number.success {{ color: #27ae60; }}
            .stat-number.warning {{ color: #f39c12; }}
            .stat-number.info {{ color: #3498db; }}
            .stat-label {{
                color: #7f8c8d;
                font-size: 14px;
                text-transform: uppercase;
                letter-spacing: 0.5px;
            }}
            .content {{
                padding: 40px;
            }}
            .section {{
                margin-bottom: 40px;
            }}
            .section-title {{
                font-size: 22px;
                margin-bottom: 20px;
                color: #2c3e50;
                display: flex;
                align-items: center;
                gap: 10px;
            }}
            .mapped-table {{
                width: 100%;
                border-collapse: collapse;
                background: white;
                border-radius: 8px;
                overflow: hidden;
                box-shadow: 0 2px 8px rgba(0,0,0,0.1);
            }}
            .mapped-table th {{
                background: #667eea;
                color: white;
                padding: 15px;
                text-align: left;
                font-weight: 600;
            }}
            .missing-list {{
                list-style: none;
                padding: 0;
            }}
            .actions {{
                display: flex;
                gap: 15px;
                justify-content: center;
                padding: 30px;
                background: #f8f9fa;
                border-top: 1px solid #ecf0f1;
            }}
            .btn {{
                padding: 12px 30px;
                border-radius: 8px;
                text-decoration: none;
                font-weight: 600;
                transition: all 0.3s;
                display: inline-flex;
                align-items: center;
                gap: 8px;
            }}
            .btn-primary {{
                background: #667eea;
                color: white;
            }}
            .btn-primary:hover {{
                background: #5568d3;
                transform: translateY(-2px);
                box-shadow: 0 4px 12px rgba(102,126,234,0.3);
            }}
            .btn-secondary {{
                background: #27ae60;
                color: white;
            }}
            .btn-secondary:hover {{
                background: #229954;
                transform: translateY(-2px);
                box-shadow: 0 4px 12px rgba(39,174,96,0.3);
            }}
        </style>
    </head>
    <body>
        <div class="container">
            <div class="header">
                <h1>📧 Mapeamento Comercial ↔ Email</h1>
                <p>Visão geral da cobertura de notificações para relatórios de visitas</p>
            </div>

            <div class="stats">
                <div class="stat-card">
                    <div class="stat-number info">{len(comercial_names)}</div>
                    <div class="stat-label">Total Comerciais</div>
                </div>
                <div class="stat-card">
                    <div class="stat-number success">{len(mapped)}</div>
                    <div class="stat-label">Mapeados</div>
                </div>
                <div class="stat-card">
                    <div class="stat-number warning">{len(missing)}</div>
                    <div class="stat-label">Não Mapeados</div>
                </div>
            </div>

            <div class="content">
                <div class="section">
                    <div class="section-title">
                        <span>✅</span>
                        <span>Comerciais com Email Configurado</span>
                    </div>
                    <table class="mapped-table">
                        <thead>
                            <tr>
                                <th>Comercial</th>
                                <th>Email</th>
                            </tr>
                        </thead>
                        <tbody>
                            {mapped_rows}
                        </tbody>
                    </table>
                </div>

                <div class="section">
                    <div class="section-title">
                        <span>⚠️</span>
                        <span>Comerciais sem Email Configurado</span>
                    </div>
                    <ul class="missing-list">
                        {missing_items}
                    </ul>
                </div>
            </div>

            <div class="actions">
                <a href="/dashboard" class="btn btn-primary">← Voltar ao Dashboard</a>
                <a href="/debug/test-email" class="btn btn-secondary">📨 Testar Email</a>
            </div>
        </div>
    </body>
    </html>
    """

@app.route('/debug/test-simple-html')
def debug_test_simple_html():
    """Simple test to verify HTML is being returned."""
    return """<!DOCTYPE html>
<html>
<head>
    <title>Simple HTML Test</title>
</head>
<body style="font-family: Arial; padding: 50px; text-align: center;">
    <h1 style="color: #667eea;">✅ This is HTML!</h1>
    <p>If you see this formatted page, Flask IS serving HTML correctly.</p>
    <p>If you see raw code or JSON, there's a caching/routing issue.</p>
</body>
</html>
"""

@app.route('/debug/test-email')
@login_required
def debug_test_email():
    """Test email notification system by sending a test message."""
    user_email = normalize_email(session.get('user_email'))

    if user_email not in ADMIN_EMAILS:
        return f"""
        <!DOCTYPE html>
        <html>
        <head>
            <title>Acesso Negado</title>
            <meta charset="UTF-8">
            <style>
                body {{ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; }}
                .container {{ background: white; padding: 40px; border-radius: 12px; max-width: 500px; box-shadow: 0 10px 40px rgba(0,0,0,0.2); text-align: center; }}
                h1 {{ color: #e74c3c; margin-bottom: 20px; }}
                p {{ color: #666; line-height: 1.6; }}
                a {{ display: inline-block; margin-top: 20px; padding: 12px 30px; background: #667eea; color: white; text-decoration: none; border-radius: 6px; transition: all 0.3s; }}
                a:hover {{ background: #5568d3; transform: translateY(-2px); }}
            </style>
        </head>
        <body>
            <div class="container">
                <h1>🚫 Acesso Negado</h1>
                <p>Apenas administradores principais podem acessar esta ferramenta.</p>
                <a href="/dashboard">← Voltar ao Dashboard</a>
            </div>
        </body>
        </html>
        """, 403

    # Check if SMTP is enabled
    if not SMTP_ENABLED:
        return f"""
        <!DOCTYPE html>
        <html>
        <head>
            <title>SMTP Desativado</title>
            <meta charset="UTF-8">
            <style>
                body {{ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; }}
                .container {{ background: white; padding: 40px; border-radius: 12px; max-width: 600px; box-shadow: 0 10px 40px rgba(0,0,0,0.2); }}
                h1 {{ color: #f39c12; margin-bottom: 20px; }}
                .info {{ background: #fff3cd; padding: 20px; border-radius: 8px; border-left: 4px solid #f39c12; margin: 20px 0; }}
                .info p {{ color: #856404; line-height: 1.8; margin: 8px 0; }}
                code {{ background: #f8f9fa; padding: 2px 6px; border-radius: 3px; font-family: 'Courier New', monospace; color: #e74c3c; }}
                a {{ display: inline-block; margin-top: 20px; padding: 12px 30px; background: #667eea; color: white; text-decoration: none; border-radius: 6px; transition: all 0.3s; }}
                a:hover {{ background: #5568d3; transform: translateY(-2px); }}
            </style>
        </head>
        <body>
            <div class="container">
                <h1>⚠️ SMTP Não Configurado</h1>
                <div class="info">
                    <p><strong>O sistema de notificações por email está desativado.</strong></p>
                    <p>Para ativar, configure as seguintes variáveis de ambiente:</p>
                    <ul style="margin-top: 10px;">
                        <li><code>SMTP_ENABLED=true</code></li>
                        <li><code>SMTP_SERVER=smtp.gmail.com</code></li>
                        <li><code>SMTP_PORT=587</code></li>
                        <li><code>SMTP_USERNAME=seu-email@gmail.com</code></li>
                        <li><code>SMTP_PASSWORD=sua-senha-app</code></li>
                    </ul>
                </div>
                <a href="/dashboard">← Voltar ao Dashboard</a>
            </div>
        </body>
        </html>
        """

    # Try to send test email
    try:
        msg = MIMEMultipart('alternative')
        msg['Subject'] = 'Globale RC: ✅ Teste de Notificação - Sales Dashboard'
        msg['From'] = SMTP_USERNAME
        msg['To'] = user_email

        # HTML body for test email
        html_body = f"""<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
</head>
<body style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; line-height: 1.6; color: #333; max-width: 600px; margin: 0 auto; padding: 20px; background-color: #f5f5f5;">
    <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 45px 30px; border-radius: 12px 12px 0 0; text-align: center; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">
        <div style="background: rgba(255, 255, 255, 0.95); display: inline-block; padding: 12px 28px; border-radius: 8px; margin-bottom: 24px; box-shadow: 0 2px 12px rgba(0,0,0,0.15);">
            <span style="font-size: 26px; font-weight: 700; letter-spacing: 2px; color: #667eea; text-transform: uppercase;">Globale RC</span>
        </div>
        <h1 style="color: white; margin: 0; font-size: 28px; font-weight: 600; text-shadow: 0 2px 4px rgba(0,0,0,0.2);">✅ Teste de Email</h1>
    </div>
    <div style="background: white; padding: 40px 35px; border-radius: 0 0 12px 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">
        <h2 style="color: #667eea; margin-top: 0; font-size: 22px; font-weight: 600;">Sistema de Notificações Funcionando!</h2>
        <p style="color: #555; font-size: 15px; line-height: 1.7;">Este é um email de teste do <strong style="color: #333;">Sales Dashboard App</strong>.</p>
        <div style="background: linear-gradient(to right, #f0fdf4, #dcfce7); padding: 20px; border-radius: 8px; margin: 24px 0; border-left: 4px solid #27ae60; box-shadow: 0 1px 3px rgba(0,0,0,0.05);">
            <p style="margin: 0; color: #27ae60; font-size: 16px; font-weight: 600;">✓ SMTP configurado corretamente</p>
            <p style="margin: 10px 0 0 0; color: #555; font-size: 14px; line-height: 1.6;">O sistema está pronto para enviar notificações de relatórios de visitas com datas de follow-up.</p>
        </div>
        <div style="background: #f8f9fa; padding: 18px 20px; border-radius: 8px; margin: 20px 0; border: 1px solid #e9ecef;">
            <p style="margin: 0; color: #495057; font-size: 14px; line-height: 1.8;"><strong style="color: #333;">Destinatário:</strong> {user_email}</p>
            <p style="margin: 8px 0 0 0; color: #495057; font-size: 14px; line-height: 1.8;"><strong style="color: #333;">Servidor SMTP:</strong> {SMTP_SERVER}:{SMTP_PORT}</p>
        </div>
        <div style="border-top: 2px solid #f0f0f0; margin-top: 30px; padding-top: 20px; text-align: center;">
            <p style="color: #999; font-size: 12px; margin: 0; letter-spacing: 0.3px;">Sales Dashboard App · Globale RC</p>
            <p style="color: #bbb; font-size: 11px; margin: 5px 0 0 0;">{datetime.now().strftime('%d/%m/%Y %H:%M')}</p>
        </div>
    </div>
</body>
</html>"""

        msg.attach(MIMEText(html_body, 'html'))

        with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
            server.starttls()
            server.login(SMTP_USERNAME, SMTP_PASSWORD)
            server.send_message(msg)

        return f"""
        <!DOCTYPE html>
        <html>
        <head>
            <title>Email Enviado</title>
            <meta charset="UTF-8">
            <meta http-equiv="refresh" content="5;url=/dashboard">
            <style>
                body {{ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; }}
                .container {{ background: white; padding: 50px; border-radius: 12px; max-width: 500px; box-shadow: 0 10px 40px rgba(0,0,0,0.2); text-align: center; }}
                .success-icon {{ font-size: 64px; margin-bottom: 20px; animation: bounce 0.6s; }}
                @keyframes bounce {{
                    0%, 100% {{ transform: translateY(0); }}
                    50% {{ transform: translateY(-20px); }}
                }}
                h1 {{ color: #27ae60; margin-bottom: 15px; }}
                p {{ color: #666; line-height: 1.8; margin: 10px 0; }}
                .email {{ background: #f8f9fa; padding: 10px; border-radius: 6px; color: #667eea; font-weight: 600; margin: 15px 0; }}
                .info {{ color: #95a5a6; font-size: 14px; margin-top: 20px; }}
                a {{ display: inline-block; margin-top: 20px; padding: 12px 30px; background: #667eea; color: white; text-decoration: none; border-radius: 6px; transition: all 0.3s; }}
                a:hover {{ background: #5568d3; transform: translateY(-2px); }}
            </style>
        </head>
        <body>
            <div class="container">
                <div class="success-icon">✅</div>
                <h1>Email Enviado com Sucesso!</h1>
                <p>Um email de teste foi enviado para:</p>
                <div class="email">{user_email}</div>
                <p>Verifique sua caixa de entrada (e spam) para confirmar o recebimento.</p>
                <p class="info">Você será redirecionado em 5 segundos...</p>
                <a href="/dashboard">← Voltar ao Dashboard</a>
            </div>
        </body>
        </html>
        """

    except Exception as e:
        return f"""
        <!DOCTYPE html>
        <html>
        <head>
            <title>Erro ao Enviar Email</title>
            <meta charset="UTF-8">
            <style>
                body {{ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; }}
                .container {{ background: white; padding: 40px; border-radius: 12px; max-width: 600px; box-shadow: 0 10px 40px rgba(0,0,0,0.2); }}
                h1 {{ color: #e74c3c; margin-bottom: 20px; }}
                .error {{ background: #ffe6e6; padding: 20px; border-radius: 8px; border-left: 4px solid #e74c3c; margin: 20px 0; }}
                .error p {{ color: #c0392b; line-height: 1.8; margin: 8px 0; }}
                code {{ background: #f8f9fa; padding: 2px 6px; border-radius: 3px; font-family: 'Courier New', monospace; color: #e74c3c; word-break: break-all; }}
                a {{ display: inline-block; margin-top: 20px; padding: 12px 30px; background: #667eea; color: white; text-decoration: none; border-radius: 6px; transition: all 0.3s; }}
                a:hover {{ background: #5568d3; transform: translateY(-2px); }}
            </style>
        </head>
        <body>
            <div class="container">
                <h1>❌ Erro ao Enviar Email</h1>
                <div class="error">
                    <p><strong>Falha na comunicação SMTP:</strong></p>
                    <p><code>{str(e)}</code></p>
                </div>
                <p style="color: #666; margin-top: 20px;">Verifique suas configurações SMTP e tente novamente.</p>
                <a href="/dashboard">← Voltar ao Dashboard</a>
            </div>
        </body>
        </html>
        """

# ============================================================================
# PERFORMANCE & OBJECTIVES ROUTES
# ============================================================================

@app.route('/performance')
@login_required
def performance():
    """Performance dashboard - Objectives vs Actual Sales with Year-over-Year Comparison."""
    user_email = session.get('user_email')
    user_role = get_user_role(user_email)
    
    # Get all scopes for admin/viewer, own data for comercial
    comercials_to_show = []
    if user_role == 'admin' or user_role == 'viewer':
        comercials_to_show = ['TOTAL', 'EXPORTAÇÃO', 'José Amor', 'Hélder Oliveira']
    elif user_role == 'comercial' and user_email in SALES_ACCESS_MAP:
        comercials_to_show = get_user_comercials(user_email)
    
    if not comercials_to_show:
        return f"Access denied (email={user_email}, role={user_role})", 403
    
    # Fetch data
    df_sales = fetch_data()
    df_objectives = fetch_objectives()
    
    if df_sales is None:
        return "Could not fetch sales data", 500
    
    # Parse columns
    def find_col(*keywords):
        for col in df_sales.columns:
            name = col.lower()
            if all(k in name for k in keywords):
                return col
        return None
    
    comercial_col = find_col('comercial')
    cliente_col = find_col('cliente')
    fat_col = find_col('fatura')
    quant_col = find_col('quant')
    zona_col = find_col('zona')
    familia_col = find_col('familia') or find_col('família')
    mes_col = find_col('mês') or find_col('mes')
    
    # Parse dates in sales data
    if mes_col:
        def parse_period(value):
            if value is None:
                return (None, None)
            s = str(value).strip()
            if not s:
                return (None, None)
            s = s.replace('-', '/').replace('.', '/')
            m = re.search(r"(\d{4})\D?(\d{1,2})", s)
            if m:
                year = m.group(1)
                month = m.group(2).zfill(2)
                return (year, month)
            m = re.search(r"(\d{1,2})\D?(\d{4})", s)
            if m:
                month = m.group(1).zfill(2)
                year = m.group(2)
                return (year, month)
            return (None, None)
        
        ym = df_sales[mes_col].apply(parse_period)
        df_sales['__year'] = ym.apply(lambda x: x[0])
        df_sales['__month'] = ym.apply(lambda x: x[1])
    
    # Convert numeric columns
    df_sales[fat_col] = pd.to_numeric(df_sales[fat_col], errors='coerce')
    df_sales[quant_col] = pd.to_numeric(df_sales[quant_col], errors='coerce')
    
    current_year = str(datetime.now().year)
    prev_year = str(int(current_year) - 1)
    
    # Build performance data for each comercial
    performance_data = []
    
    # Debug: List comercials available
    all_comercials_in_sales = df_sales[comercial_col].dropna().unique().tolist() if comercial_col else []
    print(f"[PERFORMANCE] Comercials in sales data: {all_comercials_in_sales}")
    print(f"[PERFORMANCE] Comercials to show: {comercials_to_show}")
    if df_objectives is not None and not df_objectives.empty:
        obj_comercials = df_objectives.get('Comercial', []).tolist() if 'Comercial' in df_objectives.columns else []
        print(f"[PERFORMANCE] Comercials in objectives: {obj_comercials}")
    
    for comercial_name in comercials_to_show:
        # Filter data by comercial
        if comercial_name == 'TOTAL':
            com_sales = df_sales.copy()
        elif comercial_name == 'EXPORTAÇÃO':
            if zona_col:
                com_sales = df_sales[df_sales[zona_col].astype(str).str.lower().str.contains('export', na=False)].copy()
            else:
                com_sales = df_sales.iloc[0:0].copy()
        else:
            com_sales = df_sales[df_sales[comercial_col] == comercial_name].copy()
        
        if com_sales.empty:
            continue
        
        # Get objectives for this comercial with robust matching
        obj_target_valor = 0
        obj_target_urnas = 0
        if df_objectives is not None and not df_objectives.empty and 'Comercial' in df_objectives.columns:
            print(f"\n[PERFORMANCE] 🔍 Matching comercial: '{comercial_name}'")
            print(f"[PERFORMANCE]   Available columns in objectives: {list(df_objectives.columns)}")
            
            # Try exact match first
            obj_row = df_objectives[df_objectives['Comercial'].str.strip() == comercial_name.strip()]
            
            if not obj_row.empty:
                print(f"[PERFORMANCE]   ✅ EXACT MATCH FOUND for '{comercial_name}'")
                print(f"[PERFORMANCE]   Row data: {obj_row.iloc[0].to_dict()}")
            else:
                print(f"[PERFORMANCE]   ❌ No exact match for '{comercial_name}'")
                print(f"[PERFORMANCE]   Comercials in sheet: {df_objectives['Comercial'].tolist()}")
                
                # If no exact match and comercial_name is not TOTAL/EXPORTAÇÃO, try case-insensitive match
                if comercial_name not in ['TOTAL', 'EXPORTAÇÃO']:
                    print(f"[PERFORMANCE]   Trying case-insensitive match...")
                    obj_row = df_objectives[df_objectives['Comercial'].str.strip().str.lower() == comercial_name.strip().lower()]
                    if not obj_row.empty:
                        print(f"[PERFORMANCE]   ✅ CASE-INSENSITIVE MATCH FOUND")
                        print(f"[PERFORMANCE]   Row data: {obj_row.iloc[0].to_dict()}")
                    else:
                        print(f"[PERFORMANCE]   ❌ Case-insensitive match also failed")
            
            if not obj_row.empty:
                try:
                    target_val = obj_row.iloc[0]['Target_Valor']
                    # Handle European format (comma as decimal separator)
                    target_val_str = str(target_val).replace(',', '.') if target_val else '0'
                    obj_target_valor = float(target_val_str)
                    print(f"[PERFORMANCE]   ✅ {comercial_name}: Target_Valor = {obj_target_valor}")
                except Exception as e:
                    print(f"[PERFORMANCE]   ❌ Error parsing Target_Valor for {comercial_name}: {e}")
                    obj_target_valor = 0
                try:
                    target_urnas = obj_row.iloc[0]['Target_Urnas']
                    # Handle European format (comma as decimal separator)
                    target_urnas_str = str(target_urnas).replace(',', '.') if target_urnas else '0'
                    obj_target_urnas = float(target_urnas_str)
                    print(f"[PERFORMANCE]   ✅ {comercial_name}: Target_Urnas = {obj_target_urnas}")
                except Exception as e:
                    print(f"[PERFORMANCE]   ❌ Error parsing Target_Urnas for {comercial_name}: {e}")
                    obj_target_urnas = 0
        elif df_objectives is None or df_objectives.empty:
            print(f"[PERFORMANCE] ⚠️  No objectives data loaded (df_objectives is None or empty)")
        elif 'Comercial' not in df_objectives.columns:
            print(f"[PERFORMANCE] ⚠️  'Comercial' column NOT found in objectives sheet. Available columns: {list(df_objectives.columns)}")
        
        # Current year (2026) data
        current_sales = com_sales[com_sales['__year'] == current_year]
        current_revenue = current_sales[fat_col].sum() if not current_sales.empty else 0
        current_urnas_rows = filter_urnas_family_rows(current_sales, familia_col)
        current_urnas = current_urnas_rows[quant_col].sum() if not current_urnas_rows.empty else 0
        
        # Previous year (2025) data
        prev_sales = com_sales[com_sales['__year'] == prev_year]
        prev_revenue = prev_sales[fat_col].sum() if not prev_sales.empty else 0
        prev_urnas_rows = filter_urnas_family_rows(prev_sales, familia_col)
        prev_urnas = prev_urnas_rows[quant_col].sum() if not prev_urnas_rows.empty else 0
        
        # Calculate percentages
        revenue_vs_objective = (current_revenue / obj_target_valor * 100) if obj_target_valor > 0 else 0
        urnas_vs_objective = (current_urnas / obj_target_urnas * 100) if obj_target_urnas > 0 else 0
        revenue_vs_prev = ((current_revenue - prev_revenue) / prev_revenue * 100) if prev_revenue > 0 else 0
        urnas_vs_prev = ((current_urnas - prev_urnas) / prev_urnas * 100) if prev_urnas > 0 else 0

        current_avg_price = (current_revenue / current_urnas) if current_urnas > 0 else 0
        prev_avg_price = (prev_revenue / prev_urnas) if prev_urnas > 0 else 0
        avg_price_vs_prev = ((current_avg_price - prev_avg_price) / prev_avg_price * 100) if prev_avg_price > 0 else 0

        # Build multi-year KPI history for explicit year-end comparison.
        history = []
        available_years = sorted([str(y) for y in com_sales['__year'].dropna().unique() if str(y).isdigit()])
        selected_years = available_years[-4:]
        previous_point = None
        for year in selected_years:
            year_sales = com_sales[com_sales['__year'] == year]
            year_revenue = float(year_sales[fat_col].sum()) if not year_sales.empty else 0.0
            year_urnas_rows = filter_urnas_family_rows(year_sales, familia_col)
            year_urnas = float(year_urnas_rows[quant_col].sum()) if not year_urnas_rows.empty else 0.0
            year_avg_price = (year_revenue / year_urnas) if year_urnas > 0 else 0.0

            yoy_revenue = None
            yoy_urnas = None
            if previous_point:
                yoy_revenue = ((year_revenue - previous_point['revenue']) / previous_point['revenue'] * 100) if previous_point['revenue'] > 0 else None
                yoy_urnas = ((year_urnas - previous_point['urnas']) / previous_point['urnas'] * 100) if previous_point['urnas'] > 0 else None

            history.append({
                'year': year,
                'revenue': year_revenue,
                'urnas': year_urnas,
                'avg_price': year_avg_price,
                'yoy_revenue': yoy_revenue,
                'yoy_urnas': yoy_urnas,
            })
            previous_point = {
                'revenue': year_revenue,
                'urnas': year_urnas,
            }
        
        performance_data.append({
            'comercial': comercial_name,
            'obj_target_valor': obj_target_valor,
            'obj_target_urnas': obj_target_urnas,
            'current_revenue': current_revenue,
            'current_urnas': current_urnas,
            'prev_revenue': prev_revenue,
            'prev_urnas': prev_urnas,
            'revenue_vs_objective': revenue_vs_objective,
            'urnas_vs_objective': urnas_vs_objective,
            'revenue_vs_prev': revenue_vs_prev,
            'urnas_vs_prev': urnas_vs_prev,
            'current_avg_price': current_avg_price,
            'prev_avg_price': prev_avg_price,
            'avg_price_vs_prev': avg_price_vs_prev,
            'revenue_delta_prev_abs': current_revenue - prev_revenue,
            'urnas_delta_prev_abs': current_urnas - prev_urnas,
            'revenue_to_go': max(0, obj_target_valor - current_revenue),
            'urnas_to_go': max(0, obj_target_urnas - current_urnas),
            'history': history,
        })
    
    # Build HTML with clean, simple layout
    html = """
    <!DOCTYPE html>
    <html>
    <head>
        <title>Performance 📊 Objetivos vs Vendas</title>
        <meta charset="UTF-8">
        <style>
            @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700;800&display=swap');
            * { margin: 0; padding: 0; box-sizing: border-box; }
            body { font-family: 'Inter', sans-serif; background: #f5f7fa; color: #3d4557; padding: 30px 20px; }
            .header { max-width: 1200px; margin: 0 auto 40px; display: flex; justify-content: space-between; align-items: center; }
            .header h1 { color: #2d3a4d; font-size: 28px; }
            .nav { display: flex; gap: 10px; }
            .nav a { padding: 10px 16px; background: rgba(100, 140, 200, 0.12); color: #4a5f8f; text-decoration: none; border-radius: 6px; font-weight: 600; font-size: 13px; }
            .nav a:hover { background: rgba(100, 140, 200, 0.2); }
            .container { max-width: 1200px; margin: 0 auto; }
            .card { background: white; border-radius: 12px; padding: 30px; margin-bottom: 25px; border: 1px solid rgba(100, 140, 200, 0.12); box-shadow: 0 2px 12px rgba(0,0,0,0.04); }
            .card-title { font-size: 22px; font-weight: 700; color: #2d3a4d; margin-bottom: 25px; border-bottom: 2px solid rgba(100, 140, 200, 0.2); padding-bottom: 12px; }
            .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px; margin-bottom: 20px; }
            .metric-box { background: linear-gradient(135deg, rgba(100, 140, 200, 0.08), rgba(100, 140, 200, 0.03)); padding: 20px; border-radius: 10px; border-left: 4px solid rgba(100, 140, 200, 0.4); }
            .metric-label { font-size: 12px; color: #6b7684; text-transform: uppercase; font-weight: 600; letter-spacing: 0.5px; margin-bottom: 8px; }
            .metric-value { font-size: 28px; font-weight: 800; color: #4a5f8f; margin-bottom: 4px; }
            .metric-sub { font-size: 13px; color: #696e7a; font-weight: 500; }
            .metric-sub.good { color: #10b981; }
            .metric-sub.warning { color: #f97316; }
            .metric-sub.danger { color: #ef4444; }
            .row { display: grid; grid-template-columns: 1fr 1fr; gap: 25px; }
            @media (max-width: 768px) { .row { grid-template-columns: 1fr; } }
            .comparison { background: rgba(100, 140, 200, 0.05); padding: 15px; border-radius: 8px; margin-top: 15px; font-size: 14px; }
            .comparison-row { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid rgba(100, 140, 200, 0.1); }
            .comparison-row:last-child { border-bottom: none; }
            .progress-bar { width: 100%; height: 8px; background: rgba(100, 140, 200, 0.1); border-radius: 4px; overflow: hidden; margin: 10px 0; }
            .progress-fill { height: 100%; background: linear-gradient(90deg, #667eea, #764ba2); border-radius: 4px; }
            .subsection-title { margin-top: 24px; margin-bottom: 10px; font-size: 15px; font-weight: 700; color: #2d3a4d; }
            .trend-table { width: 100%; border-collapse: collapse; margin-top: 6px; }
            .trend-table th { background: rgba(100, 140, 200, 0.1); color: #334155; font-size: 12px; text-transform: uppercase; letter-spacing: 0.4px; }
            .trend-table th, .trend-table td { padding: 10px 8px; border-bottom: 1px solid rgba(100, 140, 200, 0.12); text-align: left; font-size: 13px; }
            .muted-note { margin-top: 10px; color: #5b6476; font-size: 12px; }
        </style>
    </head>
    <body>
        <div class="header">
            <h1>📊 Performance - Objetivos vs Vendas</h1>
            <div class="nav">
                <a href="/dashboard">← Dashboard</a>
                <a href="/logout">Sair</a>
            </div>
        </div>
        <div class="container">
    """
    
    # Add performance card for each comercial
    for perf in performance_data:
        com = perf['comercial']
        obj_rev = perf['obj_target_valor']
        obj_urn = perf['obj_target_urnas']
        cur_rev = perf['current_revenue']
        cur_urn = perf['current_urnas']
        prev_rev = perf['prev_revenue']
        prev_urn = perf['prev_urnas']
        pct_rev = perf['revenue_vs_objective']
        pct_urn = perf['urnas_vs_objective']
        growth_rev = perf['revenue_vs_prev']
        growth_urn = perf['urnas_vs_prev']
        delta_rev_abs = perf['revenue_delta_prev_abs']
        delta_urn_abs = perf['urnas_delta_prev_abs']
        to_go_rev = perf['revenue_to_go']
        to_go_urn = perf['urnas_to_go']
        current_avg_price = perf['current_avg_price']
        prev_avg_price = perf['prev_avg_price']
        avg_price_vs_prev = perf['avg_price_vs_prev']
        history = perf['history']
        
        # Determine status colors
        rev_status = 'good' if pct_rev >= 100 else 'warning' if pct_rev >= 75 else 'danger'
        urn_status = 'good' if pct_urn >= 100 else 'warning' if pct_urn >= 75 else 'danger'

        trend_rows_html = ""
        for point in history:
            yoy_rev = point['yoy_revenue']
            yoy_urn = point['yoy_urnas']
            yoy_rev_text = f"{yoy_rev:+.1f}%" if yoy_rev is not None else "N/D"
            yoy_urn_text = f"{yoy_urn:+.1f}%" if yoy_urn is not None else "N/D"
            yoy_rev_color = '#10b981' if (yoy_rev is not None and yoy_rev >= 0) else ('#ef4444' if yoy_rev is not None else '#6b7280')
            yoy_urn_color = '#10b981' if (yoy_urn is not None and yoy_urn >= 0) else ('#ef4444' if yoy_urn is not None else '#6b7280')
            trend_rows_html += f"""
                <tr>
                    <td><strong>{point['year']}</strong></td>
                    <td>€{point['revenue']:,.0f}</td>
                    <td>{point['urnas']:,.0f}</td>
                    <td>€{point['avg_price']:,.2f}</td>
                    <td style=\"color: {yoy_rev_color};\">{yoy_rev_text}</td>
                    <td style=\"color: {yoy_urn_color};\">{yoy_urn_text}</td>
                </tr>
            """
        
        html += f"""
            <div class="card">
                <div class="card-title">👤 {com}</div>
                <div class="row">
                    <!-- FATURAÇÃO COLUMN -->
                    <div>
                        <div class="metric-box">
                            <div class="metric-label">💰 META {current_year} - FATURAÇÃO</div>
                            <div class="metric-value">€{obj_rev:,.0f}</div>
                        </div>
                        <div class="metric-box" style="margin-top: 15px;">
                            <div class="metric-label">📊 VENDIDO ATUAL ({current_year})</div>
                            <div class="metric-value">€{cur_rev:,.0f}</div>
                            <div class="progress-bar">
                                <div class="progress-fill" style="width: {min(pct_rev, 100)}%"></div>
                            </div>
                            <div class="metric-sub {rev_status}">✓ {pct_rev:.1f}% da meta atingida</div>
                        </div>
                        <div class="comparison">
                            <div class="comparison-row">
                                <span>Falta para meta:</span>
                                <strong style="color: #ef4444;">€{to_go_rev:,.0f}</strong>
                            </div>
                            <div class="comparison-row">
                                <span>vs {prev_year}:</span>
                                <strong style="color: {'#10b981' if growth_rev >= 0 else '#ef4444'};">{growth_rev:+.1f}%</strong>
                            </div>
                            <div class="comparison-row">
                                <span>Diferença absoluta:</span>
                                <strong style="color: {'#10b981' if delta_rev_abs >= 0 else '#ef4444'};">€{delta_rev_abs:+,.0f}</strong>
                            </div>
                            <div class="comparison-row">
                                <span>{prev_year} (anterior):</span>
                                <span>€{prev_rev:,.0f}</span>
                            </div>
                            <div class="comparison-row">
                                <span>Preço médio atual:</span>
                                <span>€{current_avg_price:,.2f}</span>
                            </div>
                            <div class="comparison-row">
                                <span>Preço médio vs {prev_year}:</span>
                                <strong style="color: {'#10b981' if avg_price_vs_prev >= 0 else '#ef4444'};">{avg_price_vs_prev:+.1f}%</strong>
                            </div>
                        </div>
                    </div>
                    
                    <!-- URNAS COLUMN -->
                    <div>
                        <div class="metric-box">
                            <div class="metric-label">📦 META {current_year} - URNAS</div>
                            <div class="metric-value">{obj_urn:.0f}</div>
                        </div>
                        <div class="metric-box" style="margin-top: 15px;">
                            <div class="metric-label">📊 VENDIDO ATUAL ({current_year})</div>
                            <div class="metric-value">{cur_urn:.0f}</div>
                            <div class="progress-bar">
                                <div class="progress-fill" style="width: {min(pct_urn, 100)}%"></div>
                            </div>
                            <div class="metric-sub {urn_status}">✓ {pct_urn:.1f}% da meta atingida</div>
                        </div>
                        <div class="comparison">
                            <div class="comparison-row">
                                <span>Falta para meta:</span>
                                <strong style="color: #ef4444;">{to_go_urn:.0f}</strong>
                            </div>
                            <div class="comparison-row">
                                <span>vs {prev_year}:</span>
                                <strong style="color: {'#10b981' if growth_urn >= 0 else '#ef4444'};">{growth_urn:+.1f}%</strong>
                            </div>
                            <div class="comparison-row">
                                <span>Diferença absoluta:</span>
                                <strong style="color: {'#10b981' if delta_urn_abs >= 0 else '#ef4444'};">{delta_urn_abs:+.0f}</strong>
                            </div>
                            <div class="comparison-row">
                                <span>{prev_year} (anterior):</span>
                                <span>{prev_urn:.0f}</span>
                            </div>
                            <div class="comparison-row">
                                <span>Preço médio {prev_year}:</span>
                                <span>€{prev_avg_price:,.2f}</span>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="subsection-title">Evolução KPI Multi-Ano</div>
                <table class="trend-table">
                    <tr>
                        <th>Ano</th>
                        <th>Faturação</th>
                        <th>Urnas</th>
                        <th>Preço Médio</th>
                        <th>YoY Faturação</th>
                        <th>YoY Urnas</th>
                    </tr>
                    {trend_rows_html}
                </table>
                <p class="muted-note">Comparação de fecho: foco no gap para objetivo {current_year} e na evolução vs {prev_year}, com histórico dos anos mais recentes disponíveis.</p>
            </div>
        """
    
    html += """
        </div>
    </body>
    </html>
    """
    
    return html

@app.route('/performance-report/<comercial>')
@login_required
def performance_report(comercial):
    """Detailed performance report for a specific comercial."""
    user_email = session.get('user_email')
    user_role = get_user_role(user_email)
    
    # Access control
    if user_role == 'comercial' and user_email in SALES_ACCESS_MAP:
        if comercial not in get_user_comercials(user_email):
            return f"Access denied (email={user_email}, role={user_role})", 403
    elif user_role not in ['admin', 'viewer']:
        return f"Access denied (email={user_email}, role={user_role})", 403
    
    perf = calculate_performance(comercial)
    if not perf:
        return "Sem dados disponíveis", 404
    
    # Generate PDF-friendly HTML report
    html = f"""
    <!DOCTYPE html>
    <html>
    <head>
        <title>Relatório de Desempenho - {comercial}</title>
        <style>
            * {{ margin: 0; padding: 0; box-sizing: border-box; }}
            body {{ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: white; padding: 40px; line-height: 1.6; }}
            .report-header {{ text-align: center; margin-bottom: 30px; border-bottom: 2px solid #667eea; padding-bottom: 20px; }}
            .report-header h1 {{ color: #333; font-size: 28px; }}
            .report-header p {{ color: #666; font-size: 14px; }}
            .section {{ margin: 30px 0; page-break-inside: avoid; }}
            .section-title {{ background: #667eea; color: white; padding: 12px 15px; font-size: 16px; font-weight: bold; border-radius: 4px; margin-bottom: 15px; }}
            .summary-grid {{ display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-bottom: 20px; }}
            .summary-box {{ background: #f9f9f9; border-left: 4px solid #667eea; padding: 15px; border-radius: 4px; }}
            .summary-box .label {{ font-size: 12px; color: #666; text-transform: uppercase; font-weight: bold; }}
            .summary-box .value {{ font-size: 20px; font-weight: bold; color: #333; margin: 8px 0; }}
            .summary-box .detail {{ font-size: 12px; color: #666; }}
            table {{ width: 100%; border-collapse: collapse; margin: 15px 0; }}
            table th {{ background: #f0f0f0; padding: 10px; text-align: left; font-weight: bold; border-bottom: 2px solid #ddd; }}
            table td {{ padding: 10px; border-bottom: 1px solid #eee; }}
            .footer {{ margin-top: 30px; text-align: center; color: #666; font-size: 12px; border-top: 1px solid #ddd; padding-top: 20px; }}
            @media print {{ body {{ padding: 0; }} .no-print {{ display: none; }} }}
        </style>
    </head>
    <body>
        <div class="report-header">
            <h1>Relatório de Desempenho de Vendas</h1>
            <p>{comercial} - Desempenho Anual</p>
            <p style="font-size: 12px; margin-top: 10px;">Gerado em {{}} | Globale RC</p>
        </div>
        
        <div class="section">
            <div class="section-title">📊 Resumo de Desempenho Geral</div>
            <div class="summary-grid">
                <div class="summary-box">
                    <div class="label">Meta de Faturação 2026</div>
                    <div class="value">€{perf['total_revenue_target']:,.2f}</div>
                    <div class="label" style="margin-top: 8px; font-size: 10px;">Vendido Atual (2026)</div>
                    <div class="detail">€{perf['total_revenue_current']:,.2f}</div>
                    <div class="label" style="margin-top: 4px; font-size: 10px;">Resultado 2025</div>
                    <div class="detail">€{perf['total_revenue_prev_year']:,.2f}</div>
                </div>
                <div class="summary-box">
                    <div class="label">Cumprimento de Faturação</div>
                    <div class="value">{perf['revenue_achievement_pct']:.1f}%</div>
                    <div class="label" style="margin-top: 8px; font-size: 10px;">Estado</div>
                    <div class="detail" style="color: {'#27ae60' if perf['revenue_achievement_pct'] >= 100 else '#f39c12' if perf['revenue_achievement_pct'] >= 80 else '#e74c3c'}; font-weight: bold;">
                        {'✓ Meta Atingida' if perf['revenue_achievement_pct'] >= 100 else '⚠ Em Progresso' if perf['revenue_achievement_pct'] >= 80 else '✗ Abaixo da Meta'}
                    </div>
                    <div class="label" style="margin-top: 8px; font-size: 10px;">% Para Atingir</div>
                    <div class="detail" style="color: {'#27ae60' if perf['revenue_to_target_pct'] <= 0 else '#e74c3c'}; font-weight: bold;">{perf['revenue_to_target_pct']:+.1f}%</div>
                    </div>
                </div>
                <div class="summary-box">
                    <div class="label">Meta URNAS 2026</div>
                    <div class="value">{perf['total_urnas_target']:.0f}</div>
                    <div class="label" style="margin-top: 8px; font-size: 10px;">Vendido Atual (2026)</div>
                    <div class="detail">{perf['total_urnas_current']:.0f} unidades</div>
                    <div class="label" style="margin-top: 4px; font-size: 10px;">Resultado 2025</div>
                    <div class="detail">{perf['total_urnas_prev_year']:.0f} unidades</div>
                </div>
                <div class="summary-box">
                    <div class="label">Cumprimento URNAS</div>
                    <div class="value">{perf['urnas_achievement_pct']:.1f}%</div>
                    <div class="label" style="margin-top: 8px; font-size: 10px;">Estado</div>
                    <div class="detail" style="color: {'#27ae60' if perf['urnas_achievement_pct'] >= 100 else '#f39c12' if perf['urnas_achievement_pct'] >= 80 else '#e74c3c'}; font-weight: bold;">
                        {'✓ Meta Atingida' if perf['urnas_achievement_pct'] >= 100 else '⚠ Em Progresso' if perf['urnas_achievement_pct'] >= 80 else '✗ Abaixo da Meta'}
                    </div>
                    <div class="label" style="margin-top: 8px; font-size: 10px;">% Para Atingir</div>
                    <div class="detail" style="color: {'#27ae60' if perf['urnas_to_target_pct'] <= 0 else '#e74c3c'}; font-weight: bold;">{perf['urnas_to_target_pct']:+.1f}%</div>
                </div>
                <div class="summary-box">
                    <div class="label">Comissão</div>
                    <div class="value">€{perf['commission_value']:,.2f}</div>
                    <div class="label" style="margin-top: 8px; font-size: 10px;">Taxa</div>
                    <div class="detail">{perf['commission_rate']*100:.1f}% sobre faturação real</div>
                </div>
            </div>
        </div>
        
        <div class="section">
            <div class="section-title">� Last 3 Years Results - Personal Performance</div>
            <table>
                <tr>
                    <th>Ano</th>
                    <th>Faturação</th>
                    <th>Crescimento vs Ant</th>
                    <th>Média €/URNA (Total)</th>
                    <th>Crescimento</th>
                    <th>Média €/URNA (URNAS)</th>
                    <th>Crescimento</th>
                    <th>Clientes</th>
                </tr>
                {''.join([f'''<tr>
                    <td>{item['year']}</td>
                    <td>€{item['revenue']:,.2f}</td>
                    <td>{item['growth_text']}</td>
                    <td>€{item['avg_per_urna_total']:,.2f}</td>
                    <td>{item['growth_avg_total_text']}</td>
                    <td>€{item['avg_per_urna_urnas']:,.2f}</td>
                    <td>{item['growth_avg_urnas_text']}</td>
                    <td>{item['clients']:,}</td>
                </tr>''' for item in perf['historical_data']])}
            </table>
        </div>
        
        <div class="section">
            <div class="section-title">�👥 Performance by Client</div>
            <p style="color: #666;">Client-level objectives are disabled. This report shows sales force totals only.</p>
        </div>
        
        <div class="footer">
            <p><strong>Globale RC - Sistema de Gestão de Vendas</strong></p>
            <p>Este relatório é confidencial e destinado apenas para uso interno.</p>
        </div>
        
        <div class="no-print" style="margin-top: 30px; text-align: center;">
            <button onclick="window.print()" style="padding: 10px 20px; background: #667eea; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px;">🖨️ Imprimir Relatório</button>
            <button onclick="window.history.back()" style="padding: 10px 20px; background: #ddd; color: #333; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; margin-left: 10px;">← Voltar</button>
        </div>
    </body>
    </html>
    """
    
    return html

@app.route('/setup-objectives')
@login_required
def setup_objectives():
    """Create and populate the Objetivos sheet with targets based on the previous year."""
    user_email = session.get('user_email')
    user_role = get_user_role(user_email)
    
    # Only admin can set up objectives
    if user_role != 'admin':
        return "Acesso negado - Apenas Admin", 403
    
    print("\n[SETUP] Creating Objetivos sheet...")
    
    try:
        creds = get_google_credentials()
        if not creds:
            return "No credentials", 500
        
        SPREADSHEET_ID = session.get('spreadsheet_id') or DEFAULT_SPREADSHEET_ID
        gc = gspread.authorize(creds)
        spreadsheet = gc.open_by_key(SPREADSHEET_ID)
        
        # Clear cache when generating new objectives to ensure fresh data
        clear_cache()
        
        # Fetch and analyze sales data
        df_sales = fetch_data()
        if df_sales is None:
            return "Could not fetch sales data", 500
        
        # Find columns
        def find_col(*keywords):
            for col in df_sales.columns:
                name = col.lower()
                if all(k in name for k in keywords):
                    return col
            return None
        
        comercial_col = find_col('comercial')
        cliente_col = find_col('cliente')
        fat_col = find_col('fatura')
        quant_col = find_col('quant')
        zona_col = find_col('zona')
        familia_col = find_col('familia') or find_col('família')
        mes_col = find_col('mês') or find_col('mes')
        
        if not all([comercial_col, cliente_col, fat_col, quant_col]):
            return "Missing required columns", 500
        
        # Parse numeric data
        df_sales[fat_col] = pd.to_numeric(df_sales[fat_col], errors='coerce')
        df_sales[quant_col] = pd.to_numeric(df_sales[quant_col], errors='coerce')

        # Build year column
        if mes_col:
            def parse_period(value):
                if value is None:
                    return (None, None)
                s = str(value).strip()
                if not s:
                    return (None, None)
                s = s.replace('-', '/').replace('.', '/')
                m = re.search(r"(\d{4})\D?(\d{1,2})", s)
                if m:
                    year = m.group(1)
                    month = m.group(2).zfill(2)
                    return (year, month)
                m = re.search(r"(\d{1,2})\D?(\d{4})", s)
                if m:
                    month = m.group(1).zfill(2)
                    year = m.group(2)
                    return (year, month)
                return (None, None)

            ym = df_sales[mes_col].apply(parse_period)
            df_sales['__year'] = ym.apply(lambda x: x[0])
        else:
            df_sales['__year'] = None

        # Determine previous year and growth/target values from query params
        # Support both percentage-based growth AND absolute value targets
        growth_total = (request.args.get('growth_total', '') or '').strip()
        growth_export = (request.args.get('growth_export', '') or '').strip()
        growth_comercial = (request.args.get('growth_comercial', '') or '').strip()
        
        target_total_value = request.args.get('target_total_value', '')
        target_export_value = request.args.get('target_export_value', '')
        target_comercial_value = request.args.get('target_comercial_value', '')

        def parse_growth(value):
            try:
                return float(value) if value not in (None, '') else None
            except (TypeError, ValueError):
                return None
        
        def parse_target(value):
            """Parse absolute target value, return None if empty/invalid"""
            try:
                return float(value) if value else None
            except (TypeError, ValueError):
                return None

        growth_total = parse_growth(growth_total)
        growth_export = parse_growth(growth_export)
        growth_comercial = parse_growth(growth_comercial)
        
        target_total_value = parse_target(target_total_value)
        target_export_value = parse_target(target_export_value)
        target_comercial_value = parse_target(target_comercial_value)

        has_growth_input = any(v is not None for v in [growth_total, growth_export, growth_comercial])
        has_absolute_input = any(v is not None for v in [target_total_value, target_export_value, target_comercial_value])

        # Mixed mode is allowed per scope (TOTAL/EXPORTAÇÃO/COMERCIAL).
        if not has_growth_input and not has_absolute_input:
            return "Preencha pelo menos um valor na Opção 1 (%) OU na Opção 2 (€).", 400

        prev_year = str(datetime.now().year - 1)
        years = sorted([y for y in df_sales['__year'].dropna().unique() if str(y).isdigit()])
        if prev_year not in years:
            prev_year = years[-1] if years else None
        target_year = str(int(prev_year) + 1) if prev_year and str(prev_year).isdigit() else None
        
        # Analyze totals (previous year only)
        analysis = {}

        if prev_year:
            base_data = df_sales[df_sales['__year'] == prev_year]
        else:
            base_data = df_sales.copy()

        total_revenue_all = base_data[fat_col].sum() if fat_col else 0
        urnas_all = filter_urnas_family_rows(base_data, familia_col)
        total_urnas_all = urnas_all[quant_col].sum() if quant_col else 0

        analysis['TOTAL'] = {
            'total_revenue': total_revenue_all,
            'total_urnas': total_urnas_all
        }

        if zona_col:
            export_data = base_data[base_data[zona_col].astype(str).str.lower().str.contains('export', na=False)]
        else:
            export_data = base_data.iloc[0:0].copy()

        export_revenue = export_data[fat_col].sum() if fat_col else 0
        export_urnas = filter_urnas_family_rows(export_data, familia_col)
        export_urnas_total = export_urnas[quant_col].sum() if quant_col else 0

        analysis['EXPORTAÇÃO'] = {
            'total_revenue': export_revenue,
            'total_urnas': export_urnas_total
        }
        
        for comercial in df_sales[comercial_col].unique():
            if pd.isna(comercial):
                continue
            
            comercial = str(comercial).strip()
            
            # Skip if this comercial is already in analysis (e.g., EXPORTAÇÃO was added as a scope)
            # Also skip if comercial name contains "export" since that's the EXPORTAÇÃO scope
            if comercial in analysis or 'export' in comercial.lower():
                continue
            
            comercial_data = df_sales[df_sales[comercial_col] == comercial]
            if prev_year:
                comercial_data = comercial_data[comercial_data['__year'] == prev_year]
            
            # Total revenue and URNAS for comercial
            total_revenue = comercial_data[fat_col].sum()
            
            # URNAS: strict family filter
            urnas_data = filter_urnas_family_rows(comercial_data, familia_col)
            total_urnas = urnas_data[quant_col].sum()
            
            # Sales force totals only (no client-level objectives)
            analysis[comercial] = {
                'total_revenue': total_revenue,
                'total_urnas': total_urnas
            }
        
        # Create or update Objetivos sheet
        sheet_exists = False
        worksheet = None
        
        for sheet in spreadsheet.worksheets():
            if sheet.title.lower() == 'objetivos':
                sheet_exists = True
                worksheet = sheet
                break
        
        if not sheet_exists:
            print("[SETUP] Creating new Objetivos sheet...")
            worksheet = spreadsheet.add_worksheet(title="Objetivos", rows=200, cols=5)
        else:
            print("[SETUP] Updating existing Objetivos sheet...")
        
        # Prepare data with mixed mode support by scope.
        # Priority per scope: absolute value (€) > percentage (%) > baseline (no change)
        
        headers = ["Comercial", "Cliente", "Target_Valor", "Target_Urnas", "Period"]
        data_rows = [headers]
        
        for comercial, comercial_data in sorted(analysis.items()):
            if comercial == 'TOTAL':
                absolute_target = target_total_value
                growth_value = growth_total
            elif comercial == 'EXPORTAÇÃO':
                absolute_target = target_export_value
                growth_value = growth_export
            else:
                absolute_target = target_comercial_value
                growth_value = growth_comercial

            if absolute_target is not None:
                total_revenue_target = absolute_target
                if comercial_data['total_revenue'] > 0:
                    revenue_ratio = absolute_target / comercial_data['total_revenue']
                    total_urnas_target = comercial_data['total_urnas'] * revenue_ratio
                else:
                    total_urnas_target = comercial_data['total_urnas']
            elif growth_value is not None:
                growth_factor = 1 + (growth_value / 100.0)
                total_revenue_target = comercial_data['total_revenue'] * growth_factor
                total_urnas_target = comercial_data['total_urnas'] * growth_factor
            else:
                total_revenue_target = comercial_data['total_revenue']
                total_urnas_target = comercial_data['total_urnas']
            
            data_rows.append([
                comercial,
                "Total",
                round(total_revenue_target, 2),
                round(total_urnas_target, 0),
                "Annual"
            ])
        
        # Write to sheet
        worksheet.clear()
        worksheet.update(data_rows, range_name='A1')
        
        print(f"[SETUP] Wrote {len(data_rows)-1} objectives")
        
        # Format header
        worksheet.format("A1:E1", {
            "backgroundColor": {"red": 0.4, "green": 0.6, "blue": 1.0},
            "textFormat": {"bold": True, "foregroundColor": {"red": 1, "green": 1, "blue": 1}}
        })
        
        # Prepare success message showing which mode was used
        def describe_scope(abs_value, growth_value):
            if abs_value is not None:
                return f"€{abs_value:,.2f}"
            if growth_value is not None:
                return f"{growth_value:.1f}%"
            return "Base ano anterior"

        mode_description = (
            "Modo misto por âmbito: "
            f"Total={describe_scope(target_total_value, growth_total)}, "
            f"Export={describe_scope(target_export_value, growth_export)}, "
            f"Comercial={describe_scope(target_comercial_value, growth_comercial)}"
        )
        
        # Create success page
        html = f"""
        <!DOCTYPE html>
        <html>
        <head>
            <title>Setup Complete</title>
            <style>
                body {{ font-family: Arial; padding: 40px; background: #f5f5f5; }}
                .container {{ max-width: 600px; margin: 0 auto; background: white; padding: 30px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }}
                h1 {{ color: #27ae60; }}
                .success-box {{ background: #d4edda; border-left: 4px solid #27ae60; padding: 15px; border-radius: 4px; margin: 20px 0; }}
                .info-box {{ background: #cce5ff; border-left: 4px solid #0066cc; padding: 15px; border-radius: 4px; margin: 20px 0; font-size: 14px; }}
                .stats {{ background: #f9f9f9; padding: 15px; border-radius: 4px; margin: 15px 0; }}
                .stats strong {{ color: #667eea; }}
                a {{ display: inline-block; margin-top: 20px; padding: 10px 20px; background: #667eea; color: white; text-decoration: none; border-radius: 4px; }}
                a:hover {{ background: #5568d3; }}
            </style>
        </head>
        <body>
            <div class="container">
                <h1>✅ Folha Objetivos Criada!</h1>
                
                <div class="success-box">
                    <strong>Sucesso!</strong> A folha 'Objetivos' foi criada e preenchida com metas de vendas para {target_year or 'o próximo ano'}.
                </div>
                
                <div class="info-box">
                    <strong>📊 Detalhes da Análise:</strong><br>
                    • Analisadas vendas do ano anterior para TOTAL, EXPORTAÇÃO e cada comercial<br>
                    • Extraídas faturação real (€) e quantidades URNAS para cada âmbito<br>
                    • Modo de cálculo utilizado: {mode_description}<br>
                    • Criadas linhas para objetivos TOTAL, EXPORTAÇÃO e comerciais
                </div>
                
                <div class="stats">
                    <strong>Cobertura:</strong><br>
                    • 2 Comerciais: Jose Amor, Helder Oliveira<br>
                    • Apenas totais da força de vendas (sem divisão por cliente)<br>
                    • Ano base utilizado: {prev_year or 'N/D'}
                </div>
                
                <div class="info-box">
                    <strong>📈 Próximos Passos:</strong><br>
                    1. Revise a folha 'Objetivos' nas suas Google Sheets<br>
                    2. Ajuste as metas se necessário<br>
                    3. Visite /performance para ver o dashboard<br>
                    4. Acompanhe a % de cumprimento para cada comercial e cliente
                </div>
                
                <a href="/performance">📊 Ver Dashboard de Desempenho →</a><br>
                <a href="/dashboard">← Voltar ao Dashboard</a>
            </div>
        </body>
        </html>
        """
        
        return html
        
    except Exception as e:
        print(f"[SETUP] Error: {e}")
        import traceback
        traceback.print_exc()
        return f"Error: {str(e)}", 500


@app.route('/salesforce-objectives-planner')
@login_required
def salesforce_objectives_planner():
    """Admin planner to generate fair individual targets based on previous year results."""
    user_email = session.get('user_email')
    user_role = get_user_role(user_email)
    if user_role != 'admin':
        return "Acesso negado - Apenas Admin", 403

    def parse_float_arg(name, default):
        raw = request.args.get(name, str(default))
        raw = (raw or '').strip().replace(' ', '').replace(',', '.')
        try:
            return float(raw)
        except (TypeError, ValueError):
            return float(default)

    target_year = int(parse_float_arg('target_year', datetime.now().year))
    company_target = parse_float_arg('company_target', 6300000)
    base_growth_pct = parse_float_arg('base_growth_pct', 3)
    weight_share = parse_float_arg('weight_share', 70)
    weight_growth = parse_float_arg('weight_growth', 30)
    avg_price_target = parse_float_arg('avg_price_target', 440)
    company_units_min = parse_float_arg('company_units_min', 14000)
    company_units_max = parse_float_arg('company_units_max', 15000)
    company_price_min = parse_float_arg('company_price_min', 430)
    company_price_max = parse_float_arg('company_price_max', 450)
    company_national_incursion_pct = parse_float_arg('company_national_incursion_pct', 12)
    company_export_pct = parse_float_arg('company_export_pct', 3.5)
    company_production_monthly = parse_float_arg('company_production_monthly', 1227)
    company_production_daily = parse_float_arg('company_production_daily', 64.56)
    company_production_annual = parse_float_arg('company_production_annual', 14728)
    apply_to_sheet = request.args.get('apply') == '1'

    if weight_share < 0:
        weight_share = 0
    if weight_growth < 0:
        weight_growth = 0
    if (weight_share + weight_growth) <= 0:
        weight_share, weight_growth = 70.0, 30.0

    total_weight = weight_share + weight_growth
    share_factor = weight_share / total_weight
    growth_factor = weight_growth / total_weight

    df_sales = fetch_data()
    if df_sales is None or df_sales.empty:
        return "Sem dados de vendas para planear objetivos.", 500

    def find_col(*keywords):
        for col in df_sales.columns:
            name = col.lower()
            if all(k in name for k in keywords):
                return col
        return None

    comercial_col = find_col('comercial')
    fat_col = find_col('fatura')
    quant_col = find_col('quant')
    familia_col = find_col('familia') or find_col('família')
    mes_col = find_col('mês') or find_col('mes')

    if not all([comercial_col, fat_col, quant_col, mes_col]):
        return "Colunas obrigatórias em falta (Comercial/Faturação/Quantidade/Mês).", 500

    df = df_sales.copy()
    df[fat_col] = pd.to_numeric(df[fat_col], errors='coerce').fillna(0)
    df[quant_col] = pd.to_numeric(df[quant_col], errors='coerce').fillna(0)

    def parse_year(value):
        if value is None or pd.isna(value):
            return None
        s = str(value).strip().replace('-', '/').replace('.', '/')
        m = re.search(r"(\d{4})\D?(\d{1,2})", s)
        if m:
            return m.group(1)
        m = re.search(r"(\d{1,2})\D?(\d{4})", s)
        if m:
            return m.group(2)
        return None

    df['__year'] = df[mes_col].apply(parse_year)
    valid_years = sorted([y for y in df['__year'].dropna().unique() if str(y).isdigit()])
    if not valid_years:
        return "Não foi possível identificar anos válidos nos dados.", 500

    base_year = str(target_year - 1)
    prev_year = str(target_year - 2)
    if base_year not in valid_years:
        base_year = valid_years[-1]
        prev_year = str(int(base_year) - 1)
        target_year = int(base_year) + 1

    base_df = df[df['__year'] == base_year].copy()
    prev_df = df[df['__year'] == prev_year].copy() if prev_year in valid_years else df.iloc[0:0].copy()

    analysis = []
    for comercial in sorted(base_df[comercial_col].dropna().unique().tolist()):
        comercial_name = str(comercial).strip()
        if not comercial_name:
            continue
        if 'export' in comercial_name.lower():
            continue

        c_base = base_df[base_df[comercial_col] == comercial_name]
        c_prev = prev_df[prev_df[comercial_col] == comercial_name] if not prev_df.empty else prev_df

        rev_2025 = float(c_base[fat_col].sum())
        urnas_2025 = float(filter_urnas_family_rows(c_base, familia_col)[quant_col].sum())
        rev_prev = float(c_prev[fat_col].sum()) if not c_prev.empty else 0.0

        if rev_2025 <= 0:
            continue

        growth_pct = ((rev_2025 - rev_prev) / rev_prev * 100.0) if rev_prev > 0 else None
        avg_price_2025 = (rev_2025 / urnas_2025) if urnas_2025 > 0 else avg_price_target

        analysis.append({
            'comercial': comercial_name,
            'revenue_base': rev_2025,
            'urnas_base': urnas_2025,
            'revenue_prev': rev_prev,
            'growth_pct': growth_pct,
            'avg_price_2025': avg_price_2025,
        })

    if not analysis:
        return f"Sem dados para comerciais no ano base {base_year}.", 500

    total_base = sum(x['revenue_base'] for x in analysis)
    growth_values = [x['growth_pct'] for x in analysis if x['growth_pct'] is not None]
    growth_min = min(growth_values) if growth_values else 0.0
    growth_max = max(growth_values) if growth_values else 0.0
    growth_mid = (sum(growth_values) / len(growth_values)) if growth_values else 0.0

    for row in analysis:
        row['share_2025'] = (row['revenue_base'] / total_base) if total_base > 0 else 0.0
        g = row['growth_pct'] if row['growth_pct'] is not None else growth_mid
        if growth_max > growth_min:
            row['growth_score'] = (g - growth_min) / (growth_max - growth_min)
        else:
            row['growth_score'] = 0.5

        row['fair_score'] = (share_factor * row['share_2025']) + (growth_factor * row['growth_score'])
        row['base_target'] = row['revenue_base'] * (1 + base_growth_pct / 100.0)

    base_total_target = sum(x['base_target'] for x in analysis)
    extra_pool = company_target - base_total_target
    fair_total = sum(x['fair_score'] for x in analysis)

    for row in analysis:
        fair_ratio = (row['fair_score'] / fair_total) if fair_total > 0 else (1.0 / len(analysis))
        row['target_value'] = row['base_target'] + (extra_pool * fair_ratio)
        row['target_value'] = max(0.0, row['target_value'])

    generated_total = sum(x['target_value'] for x in analysis)
    if generated_total > 0:
        correction = company_target / generated_total
        for row in analysis:
            row['target_value'] = row['target_value'] * correction

    for row in analysis:
        row['target_growth_pct'] = ((row['target_value'] / row['revenue_base']) - 1.0) * 100.0 if row['revenue_base'] > 0 else 0.0
        row['target_urnas'] = row['target_value'] / avg_price_target if avg_price_target > 0 else 0.0

    analysis = sorted(analysis, key=lambda x: x['target_value'], reverse=True)

    apply_message = ''
    company_units_target = (company_units_min + company_units_max) / 2.0 if (company_units_min > 0 and company_units_max > 0) else (company_target / avg_price_target if avg_price_target > 0 else 0)
    if apply_to_sheet:
        try:
            creds = get_google_credentials()
            if not creds:
                raise RuntimeError("No credentials")

            SPREADSHEET_ID = session.get('spreadsheet_id') or DEFAULT_SPREADSHEET_ID
            gc = gspread.authorize(creds)
            spreadsheet = gc.open_by_key(SPREADSHEET_ID)

            worksheet = None
            for sheet in spreadsheet.worksheets():
                if sheet.title.lower() == 'objetivos':
                    worksheet = sheet
                    break

            if worksheet is None:
                worksheet = spreadsheet.add_worksheet(title="Objetivos", rows=300, cols=5)

            rows = [["Comercial", "Cliente", "Target_Valor", "Target_Urnas", "Period"]]
            rows.append([
                "TOTAL",
                "Total",
                round(company_target, 2),
                round(company_units_target, 0),
                f"Annual {target_year}"
            ])
            for row in analysis:
                rows.append([
                    row['comercial'],
                    "Total",
                    round(row['target_value'], 2),
                    round(row['target_urnas'], 0),
                    f"Annual {target_year}"
                ])

            worksheet.clear()
            worksheet.update(rows, range_name='A1')
            worksheet.format("A1:E1", {
                "backgroundColor": {"red": 0.2, "green": 0.43, "blue": 0.86},
                "textFormat": {"bold": True, "foregroundColor": {"red": 1, "green": 1, "blue": 1}}
            })
            apply_message = "Objetivos gravados na sheet 'Objetivos' com sucesso."
            # Force clear all cache to ensure fresh load
            clear_cache()
            print("[SAVE] ✅ Objectives saved and cache cleared")
        except Exception as e:
            apply_message = f"Erro ao gravar na sheet: {e}"

    planner_rows_html = ''.join([
        f"""
        <tr>
            <td><strong>{row['comercial']}</strong></td>
            <td>€{row['revenue_base']:,.2f}</td>
            <td>{row['share_2025']*100:.2f}%</td>
            <td>{'N/D' if row['growth_pct'] is None else f"{row['growth_pct']:.2f}%"}</td>
            <td>€{row['target_value']:,.2f}</td>
            <td>{row['target_growth_pct']:.2f}%</td>
            <td>{row['target_urnas']:,.0f}</td>
        </tr>
        """
        for row in analysis
    ])

    # Preserve current parameters on links
    params_base = (
        f"target_year={target_year}&company_target={company_target:.2f}&base_growth_pct={base_growth_pct:.2f}"
        f"&weight_share={weight_share:.2f}&weight_growth={weight_growth:.2f}&avg_price_target={avg_price_target:.2f}"
        f"&company_units_min={company_units_min:.2f}&company_units_max={company_units_max:.2f}"
        f"&company_price_min={company_price_min:.2f}&company_price_max={company_price_max:.2f}"
        f"&company_national_incursion_pct={company_national_incursion_pct:.2f}&company_export_pct={company_export_pct:.2f}"
        f"&company_production_monthly={company_production_monthly:.2f}&company_production_daily={company_production_daily:.2f}&company_production_annual={company_production_annual:.2f}"
    )

    html = f"""
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>Planeador de Objetivos - Força de Vendas</title>
        <style>
            body {{ font-family: 'Inter', Arial, sans-serif; background: #f4f6f8; margin: 0; padding: 24px; color: #1f2937; }}
            .container {{ max-width: 1280px; margin: 0 auto; }}
            .card {{ background: #fff; border: 1px solid #dbe3ef; border-radius: 10px; padding: 20px; margin-bottom: 16px; box-shadow: 0 2px 8px rgba(15,23,42,0.05); }}
            h1 {{ margin: 0 0 12px 0; color: #0f172a; }}
            .muted {{ color: #64748b; font-size: 14px; }}
            .grid {{ display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }}
            label {{ font-size: 12px; font-weight: 700; color: #334155; text-transform: uppercase; letter-spacing: 0.4px; }}
            input {{ width: 100%; padding: 10px; border: 1px solid #cbd5e1; border-radius: 6px; font-size: 14px; }}
            .actions {{ display: flex; gap: 10px; flex-wrap: wrap; margin-top: 12px; }}
            .btn {{ display: inline-block; padding: 10px 14px; border-radius: 6px; text-decoration: none; font-weight: 700; font-size: 13px; border: 1px solid transparent; }}
            .btn-primary {{ background: #2563eb; color: #fff; }}
            .btn-success {{ background: #059669; color: #fff; }}
            .btn-ghost {{ background: #fff; color: #334155; border-color: #cbd5e1; }}
            table {{ width: 100%; border-collapse: collapse; margin-top: 10px; }}
            th, td {{ padding: 10px 8px; border-bottom: 1px solid #e5e7eb; text-align: left; font-size: 14px; }}
            th {{ background: #eff6ff; color: #1e3a8a; text-transform: uppercase; font-size: 12px; letter-spacing: 0.4px; }}
            .ok {{ background: #ecfdf5; border: 1px solid #a7f3d0; color: #065f46; padding: 10px 12px; border-radius: 6px; }}
            .warn {{ background: #fffbeb; border: 1px solid #fde68a; color: #92400e; padding: 10px 12px; border-radius: 6px; }}
        </style>
    </head>
    <body>
        <div class="container">
            <div class="card">
                <h1>🎯 Planeador de Objetivos da Força de Vendas</h1>
                <p class="muted">Critério justo e replicável: base no ano {base_year} + distribuição do gap por peso de faturação e performance de crescimento.</p>
                {f'<div class="ok">{apply_message}</div>' if apply_message and 'sucesso' in apply_message.lower() else (f'<div class="warn">{apply_message}</div>' if apply_message else '')}
            </div>

            <div class="card">
                <form method="get" action="/salesforce-objectives-planner">
                    <div class="grid">
                        <div><label>Ano Objetivo</label><input type="number" name="target_year" value="{target_year}"></div>
                        <div><label>Objetivo Empresa (€)</label><input type="number" step="0.01" name="company_target" value="{company_target:.2f}"></div>
                        <div><label>Crescimento Base (%)</label><input type="number" step="0.1" name="base_growth_pct" value="{base_growth_pct:.2f}"></div>
                        <div><label>Peso Faturação 2025 (%)</label><input type="number" step="0.1" name="weight_share" value="{weight_share:.2f}"></div>
                        <div><label>Peso Performance Cresc. (%)</label><input type="number" step="0.1" name="weight_growth" value="{weight_growth:.2f}"></div>
                        <div><label>Preço Médio Objetivo (€/un)</label><input type="number" step="0.01" name="avg_price_target" value="{avg_price_target:.2f}"></div>
                        <div><label>Unidades Objetivo (min)</label><input type="number" step="1" name="company_units_min" value="{company_units_min:.0f}"></div>
                        <div><label>Unidades Objetivo (max)</label><input type="number" step="1" name="company_units_max" value="{company_units_max:.0f}"></div>
                        <div><label>Preço médio global min (€/un)</label><input type="number" step="0.01" name="company_price_min" value="{company_price_min:.2f}"></div>
                        <div><label>Preço médio global max (€/un)</label><input type="number" step="0.01" name="company_price_max" value="{company_price_max:.2f}"></div>
                        <div><label>% incursão mercado nacional</label><input type="number" step="0.01" name="company_national_incursion_pct" value="{company_national_incursion_pct:.2f}"></div>
                        <div><label>% exportação</label><input type="number" step="0.01" name="company_export_pct" value="{company_export_pct:.2f}"></div>
                        <div><label>Produção mensal (un)</label><input type="number" step="0.01" name="company_production_monthly" value="{company_production_monthly:.2f}"></div>
                        <div><label>Produção diária (un)</label><input type="number" step="0.01" name="company_production_daily" value="{company_production_daily:.2f}"></div>
                        <div><label>Produção anual (un)</label><input type="number" step="0.01" name="company_production_annual" value="{company_production_annual:.2f}"></div>
                    </div>
                    <div class="actions">
                        <button class="btn btn-primary" type="submit">🔄 Recalcular</button>
                        <a class="btn btn-success" href="/salesforce-objectives-planner?{params_base}&apply=1">💾 Gravar na sheet Objetivos</a>
                        <a class="btn btn-ghost" href="/dashboard">← Voltar Dashboard</a>
                    </div>
                </form>
            </div>

            <div class="card">
                <h3 style="margin-top:0; color:#0f172a;">Objetivos Globais da Empresa ({target_year})</h3>
                <table>
                    <tr><th>Indicador</th><th>Objetivo</th></tr>
                    <tr><td>Faturação</td><td>€{company_target:,.2f}</td></tr>
                    <tr><td>Unidades vendidas</td><td>{company_units_min:,.0f} - {company_units_max:,.0f}</td></tr>
                    <tr><td>Preço médio/un</td><td>€{company_price_min:,.2f} - €{company_price_max:,.2f}</td></tr>
                    <tr><td>% incursão mercado nacional</td><td>{company_national_incursion_pct:.2f}%</td></tr>
                    <tr><td>% exportação</td><td>{company_export_pct:.2f}%</td></tr>
                    <tr><td>Produção mensal (un)</td><td>{company_production_monthly:,.2f}</td></tr>
                    <tr><td>Produção diária (un)</td><td>{company_production_daily:,.2f}</td></tr>
                    <tr><td>Produção anual (un)</td><td>{company_production_annual:,.2f}</td></tr>
                </table>
            </div>

            <div class="card">
                <p><strong>Ano base:</strong> {base_year} | <strong>Total base:</strong> €{total_base:,.2f} | <strong>Objetivo empresa:</strong> €{company_target:,.2f}</p>
                <p class="muted">Fórmula: Target = Base ({base_growth_pct:.2f}%) + distribuição do gap por score justo ({weight_share:.1f}% faturação, {weight_growth:.1f}% crescimento).</p>
                <table>
                    <tr>
                        <th>Comercial</th>
                        <th>Faturação {base_year}</th>
                        <th>Peso</th>
                        <th>Cresc. vs {prev_year}</th>
                        <th>Objetivo {target_year} (€)</th>
                        <th>Cresc. Objetivo</th>
                        <th>Objetivo Unidades</th>
                    </tr>
                    {planner_rows_html}
                </table>
            </div>
        </div>
    </body>
    </html>
    """

    return html

# ============================================================================
# ADMIN OBJECTIVES TRACKING - Monitor and Manage Individual Objectives
# ============================================================================

@app.route('/admin-objectives-tracking', methods=['GET'])
@login_required
def admin_objectives_tracking():
    """Display all objectives in a table with edit/delete options."""
    user_email = session.get('user_email')
    user_role = get_user_role(user_email)
    if user_role != 'admin':
        return "Acesso negado - Apenas Admin", 403
    
    df_objectives = fetch_objectives()
    if df_objectives is None or df_objectives.empty:
        objectives_html = "<tr><td colspan='10' style='text-align: center; padding: 20px; color: #999;'>Nenhum objetivo definido ainda</td></tr>"
        total_objectives = 0
    else:
        total_objectives = len(df_objectives)
        objectives_rows = []
        for idx, row in df_objectives.iterrows():
            comercial = row.get('Comercial', '')
            cliente = row.get('Cliente', '')
            target_valor = row.get('Target_Valor', '')
            target_urnas = row.get('Target_Urnas', '')
            period = row.get('Period', '')
            
            row_html = f"""
            <tr>
                <td><strong>{comercial}</strong></td>
                <td>{cliente}</td>
                <td>€ {target_valor}</td>
                <td>{target_urnas}</td>
                <td>{period}</td>
                <td>
                    <button class="btn btn-small btn-primary" onclick="editObjective({idx}, '{comercial}', '{cliente}', '{target_valor}', '{target_urnas}', '{period}')">✏️ Editar</button>
                    <button class="btn btn-small btn-danger" onclick="deleteObjective({idx}, '{comercial}')">🗑️ Apagar</button>
                </td>
            </tr>
            """
            objectives_rows.append(row_html)
        objectives_html = "\n".join(objectives_rows)
    
    html = f"""
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>Acompanhamento de Objetivos - Admin</title>
        <style>
            * {{ margin: 0; padding: 0; box-sizing: border-box; }}
            body {{ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #f5f5f7; color: #1d1d1f; line-height: 1.6; }}
            .container {{ max-width: 1200px; margin: 0 auto; padding: 20px; }}
            .header {{ display: flex; justify-content: space-between; align-items: center; margin-bottom: 30px; padding-bottom: 20px; border-bottom: 2px solid #e5e7eb; }}
            .header h1 {{ font-size: 28px; font-weight: 600; }}
            .header .stats {{ display: flex; gap: 30px; align-items: center; }}
            .stat {{ text-align: center; }}
            .stat-value {{ font-size: 24px; font-weight: 700; color: #0066cc; }}
            .stat-label {{ font-size: 12px; color: #666; text-transform: uppercase; letter-spacing: 0.5px; }}
            .actions {{ display: flex; gap: 12px; }}
            .btn {{ padding: 10px 16px; border: none; border-radius: 6px; cursor: pointer; font-weight: 600; font-size: 14px; transition: all 0.2s; text-decoration: none; display: inline-flex; align-items: center; gap: 6px; }}
            .btn-primary {{ background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%); color: white; }}
            .btn-primary:hover {{ transform: translateY(-2px); box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3); }}
            .btn-success {{ background: linear-gradient(135deg, #10b981 0%, #059669 100%); color: white; }}
            .btn-success:hover {{ transform: translateY(-2px); box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3); }}
            .btn-danger {{ background: #dc2626; color: white; }}
            .btn-danger:hover {{ background: #b91c1c; }}
            .btn-small {{ padding: 6px 12px; font-size: 12px; }}
            .btn-ghost {{ background: transparent; color: #666; border: 1px solid #ddd; }}
            .btn-ghost:hover {{ background: #f5f5f7; }}
            table {{ width: 100%; border-collapse: collapse; background: white; border-radius: 8px; overflow: hidden; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }}
            th {{ background: linear-gradient(135deg, #f3f4f6 0%, #e5e7eb 100%); padding: 12px 16px; text-align: left; font-weight: 600; font-size: 13px; text-transform: uppercase; letter-spacing: 0.5px; color: #4b5563; border-bottom: 2px solid #d1d5db; }}
            td {{ padding: 14px 16px; border-bottom: 1px solid #e5e7eb; }}
            tr:hover {{ background: #f9fafb; }}
            tr:last-child td {{ border-bottom: none; }}
            .badge {{ display: inline-block; padding: 4px 10px; border-radius: 12px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.3px; }}
            .badge-success {{ background: #d1fae5; color: #065f46; }}
            .badge-info {{ background: #dbeafe; color: #0c4a6e; }}
            .modal {{ display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000; align-items: center; justify-content: center; }}
            .modal.active {{ display: flex; }}
            .modal-content {{ background: white; padding: 30px; border-radius: 12px; max-width: 500px; box-shadow: 0 20px 60px rgba(0,0,0,0.3); }}
            .modal-header {{ font-size: 20px; font-weight: 700; margin-bottom: 20px; }}
            .form-group {{ margin-bottom: 16px; }}
            .form-group label {{ display: block; font-weight: 600; margin-bottom: 6px; font-size: 13px; }}
            .form-group input {{ width: 100%; padding: 10px 12px; border: 1px solid #d1d5db; border-radius: 6px; font-size: 14px; }}
            .form-actions {{ display: flex; gap: 12px; margin-top: 24px; }}
            .empty-state {{ text-align: center; padding: 60px 20px; }}
            .empty-state-icon {{ font-size: 48px; margin-bottom: 16px; }}
            .empty-state-text {{ color: #999; font-size: 16px; }}
        </style>
    </head>
    <body>
        <div class="container">
            <div class="header">
                <div>
                    <h1>📊 Acompanhamento de Objetivos</h1>
                    <p style="color: #666; font-size: 14px; margin-top: 4px;">Gestão centralizada de objetivos individuais definidos</p>
                </div>
                <div class="stats">
                    <div class="stat">
                        <div class="stat-value">{total_objectives}</div>
                        <div class="stat-label">Objetivos</div>
                    </div>
                    <div class="actions">
                        <a href="/salesforce-objectives-planner" class="btn btn-primary">➕ Criar Novos Objetivos</a>
                        <a href="/dashboard" class="btn btn-ghost">← Voltar</a>
                    </div>
                </div>
            </div>

            <div style="background: white; border-radius: 8px; overflow: hidden; box-shadow: 0 1px 3px rgba(0,0,0,0.1);">
                <table>
                    <thead>
                        <tr>
                            <th>Comercial</th>
                            <th>Cliente</th>
                            <th>Target Faturação</th>
                            <th>Target Urnas</th>
                            <th>Período</th>
                            <th style="text-align: center; width: 200px;">Ações</th>
                        </tr>
                    </thead>
                    <tbody>
                        {objectives_html}
                    </tbody>
                </table>
            </div>

            <div style="margin-top: 20px; padding: 16px; background: #f0f9ff; border-left: 4px solid #0066cc; border-radius: 6px; font-size: 13px; color: #333;">
                <strong>💡 Dica:</strong> Para criar ou atualizar objetivos em massa, use o <a href="/salesforce-objectives-planner" style="color: #0066cc; text-decoration: none; font-weight: 600;">Planeador de Objetivos</a>.
            </div>
        </div>

        <!-- Edit Modal -->
        <div id="editModal" class="modal">
            <div class="modal-content">
                <div class="modal-header">Editar Objetivo</div>
                <form id="editForm">
                    <input type="hidden" id="editIdx">
                    <div class="form-group">
                        <label>Comercial (somente leitura)</label>
                        <input type="text" id="editComercial" readonly style="background: #f5f5f7; color: #999;">
                    </div>
                    <div class="form-group">
                        <label>Cliente</label>
                        <input type="text" id="editCliente">
                    </div>
                    <div class="form-group">
                        <label>Target Faturação (€)</label>
                        <input type="number" id="editTargetValor" step="0.01">
                    </div>
                    <div class="form-group">
                        <label>Target Urnas</label>
                        <input type="number" id="editTargetUrnas" step="1">
                    </div>
                    <div class="form-group">
                        <label>Período</label>
                        <input type="text" id="editPeriod" placeholder="Ex: 2026">
                    </div>
                    <div class="form-actions">
                        <button type="button" class="btn btn-primary" onclick="saveObjective()">💾 Guardar Alterações</button>
                        <button type="button" class="btn btn-ghost" onclick="closeEditModal()">Cancelar</button>
                    </div>
                </form>
            </div>
        </div>

        <script>
            function editObjective(idx, comercial, cliente, targetValor, targetUrnas, period) {{
                document.getElementById('editIdx').value = idx;
                document.getElementById('editComercial').value = comercial;
                document.getElementById('editCliente').value = cliente;
                document.getElementById('editTargetValor').value = targetValor;
                document.getElementById('editTargetUrnas').value = targetUrnas;
                document.getElementById('editPeriod').value = period;
                document.getElementById('editModal').classList.add('active');
            }}

            function closeEditModal() {{
                document.getElementById('editModal').classList.remove('active');
            }}

            function saveObjective() {{
                const idx = document.getElementById('editIdx').value;
                const comercial = document.getElementById('editComercial').value;
                const cliente = document.getElementById('editCliente').value;
                const targetValor = document.getElementById('editTargetValor').value;
                const targetUrnas = document.getElementById('editTargetUrnas').value;
                const period = document.getElementById('editPeriod').value;

                fetch('/api/update-objective', {{
                    method: 'POST',
                    headers: {{'Content-Type': 'application/json'}},
                    body: JSON.stringify({{idx: idx, comercial: comercial, cliente: cliente, targetValor: targetValor, targetUrnas: targetUrnas, period: period}})
                }})
                .then(r => r.json())
                .then(data => {{
                    if (data.success) {{
                        alert('✅ Objetivo atualizado com sucesso!');
                        location.reload();
                    }} else {{
                        alert('❌ Erro: ' + data.message);
                    }}
                }})
                .catch(e => alert('❌ Erro ao atualizar: ' + e));
            }}

            function deleteObjective(idx, comercial) {{
                if (confirm(`Tem a certeza que quer apagar o objetivo de ${{comercial}}?`)) {{
                    fetch('/api/delete-objective', {{
                        method: 'POST',
                        headers: {{'Content-Type': 'application/json'}},
                        body: JSON.stringify({{idx: idx, comercial: comercial}})
                    }})
                    .then(r => r.json())
                    .then(data => {{
                        if (data.success) {{
                            alert('✅ Objetivo apagado com sucesso!');
                            location.reload();
                        }} else {{
                            alert('❌ Erro: ' + data.message);
                        }}
                    }})
                    .catch(e => alert('❌ Erro ao apagar: ' + e));
                }}
            }}

            // Close modal on Escape key
            document.addEventListener('keydown', function(e) {{
                if (e.key === 'Escape') {{
                    closeEditModal();
                }}
            }});
        </script>
    </body>
    </html>
    """
    
    return html

@app.route('/api/update-objective', methods=['POST'])
@login_required
def api_update_objective():
    """Update an objective row in the 'Objetivos' sheet."""
    user_email = session.get('user_email')
    user_role = get_user_role(user_email)
    if user_role != 'admin':
        return jsonify({'success': False, 'message': 'Acesso negado'}), 403
    
    try:
        data = request.get_json()
        idx = int(data.get('idx', 0))
        comercial = data.get('comercial', '').strip()
        cliente = data.get('cliente', '').strip()
        target_valor = str(data.get('targetValor', '')).strip()
        target_urnas = str(data.get('targetUrnas', '')).strip()
        period = data.get('period', '').strip()
        
        creds = get_google_credentials()
        if not creds:
            return jsonify({'success': False, 'message': 'Credenciais não disponíveis'}), 500
        
        SPREADSHEET_ID = session.get('spreadsheet_id') or DEFAULT_SPREADSHEET_ID
        gc = gspread.authorize(creds)
        spreadsheet = gc.open_by_key(SPREADSHEET_ID)
        
        worksheet = None
        for sheet in spreadsheet.worksheets():
            if sheet.title.lower() == 'objetivos':
                worksheet = sheet
                break
        
        if not worksheet:
            return jsonify({'success': False, 'message': 'Sheet "Objetivos" não encontrada'}), 404
        
        all_values = worksheet.get_all_values()
        if len(all_values) < 2:
            return jsonify({'success': False, 'message': 'Sheet vazia'}), 404
        
        headers = all_values[0]
        # Update row (idx+2 because row 1 is headers, idx is 0-based)
        row_index = idx + 2
        
        # Get column indices
        col_comercial = headers.index('Comercial') + 1 if 'Comercial' in headers else 1
        col_cliente = headers.index('Cliente') + 1 if 'Cliente' in headers else 2
        col_target_valor = headers.index('Target_Valor') + 1 if 'Target_Valor' in headers else 3
        col_target_urnas = headers.index('Target_Urnas') + 1 if 'Target_Urnas' in headers else 4
        col_period = headers.index('Period') + 1 if 'Period' in headers else 5
        
        worksheet.update_cell(row_index, col_cliente, cliente)
        worksheet.update_cell(row_index, col_target_valor, target_valor)
        worksheet.update_cell(row_index, col_target_urnas, target_urnas)
        worksheet.update_cell(row_index, col_period, period)
        
        # Clear cache
        cache_key = get_cache_key('objectives')
        set_cached_data(cache_key, None)
        
        print(f"[ADMIN] Updated objective for {comercial}: Cliente={cliente}, Target_Valor={target_valor}, Target_Urnas={target_urnas}, Period={period}")
        
        return jsonify({'success': True, 'message': 'Objetivo atualizado'})
    except Exception as e:
        print(f"[ADMIN] Error updating objective: {e}")
        import traceback
        traceback.print_exc()
        return jsonify({'success': False, 'message': str(e)}), 500

@app.route('/api/delete-objective', methods=['POST'])
@login_required
def api_delete_objective():
    """Delete an objective row from the 'Objetivos' sheet."""
    user_email = session.get('user_email')
    user_role = get_user_role(user_email)
    if user_role != 'admin':
        return jsonify({'success': False, 'message': 'Acesso negado'}), 403
    
    try:
        data = request.get_json()
        idx = int(data.get('idx', 0))
        comercial = data.get('comercial', '').strip()
        
        creds = get_google_credentials()
        if not creds:
            return jsonify({'success': False, 'message': 'Credenciais não disponíveis'}), 500
        
        SPREADSHEET_ID = session.get('spreadsheet_id') or DEFAULT_SPREADSHEET_ID
        gc = gspread.authorize(creds)
        spreadsheet = gc.open_by_key(SPREADSHEET_ID)
        
        worksheet = None
        for sheet in spreadsheet.worksheets():
            if sheet.title.lower() == 'objetivos':
                worksheet = sheet
                break
        
        if not worksheet:
            return jsonify({'success': False, 'message': 'Sheet "Objetivos" não encontrada'}), 404
        
        all_values = worksheet.get_all_values()
        if len(all_values) < 2:
            return jsonify({'success': False, 'message': 'Sheet vazia'}), 404
        
        # Delete row (idx+2 because row 1 is headers, idx is 0-based)
        row_index = idx + 2
        worksheet.delete_rows(row_index)
        
        # Clear cache
        cache_key = get_cache_key('objectives')
        set_cached_data(cache_key, None)
        
        print(f"[ADMIN] Deleted objective row {row_index} for {comercial}")
        
        return jsonify({'success': True, 'message': 'Objetivo apagado'})
    except Exception as e:
        print(f"[ADMIN] Error deleting objective: {e}")
        import traceback
        traceback.print_exc()
        return jsonify({'success': False, 'message': str(e)}), 500

# ============================================================================
# INVENTORY MODULE ROUTES (Separate System - No Dependencies on Sales)
# ============================================================================

def has_inventory_access(user_role, user_email):
    """Check if user has access to inventory module"""
    # Admins always have access
    if user_role == 'admin':
        return True
    # Warehouse team has access
    if user_role == 'warehouse' or normalize_email(user_email) in WAREHOUSE_EMAILS:
        return True
    return False

def has_dashboard_access(user_role, user_email):
    """Check if user has access to sales dashboard"""
    # Admins always have access
    if user_role == 'admin':
        return True
    # Sales team (comercial, viewer) has access
    if user_role in ['comercial', 'viewer']:
        return True
    # Warehouse staff cannot access sales dashboard
    return False

@app.route('/inventory')
@login_required
def inventory():
    """Display inventory dashboard"""
    user_email = normalize_email(session.get('user_email'))
    user_role = get_user_role(user_email)
    
    # Check access
    if not has_inventory_access(user_role, user_email):
        return f"""
        <!DOCTYPE html>
        <html>
        <head>
            <title>Acesso Negado</title>
            <style>
                body {{ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #f5f7fa 0%, #eef2f5 100%); margin: 0; padding: 40px; }}
                .container {{ max-width: 500px; margin: 60px auto; background: white; padding: 40px; border-radius: 8px; box-shadow: 0 4px 16px rgba(100, 140, 200, 0.1); text-align: center; }}
                h1 {{ color: #d32f2f; margin-top: 0; }}
                p {{ color: #666; line-height: 1.6; margin: 20px 0; }}
                .info-box {{ background: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; margin: 20px 0; border-radius: 4px; text-align: left; }}
                .button {{ display: inline-block; padding: 12px 24px; background: #667eea; color: white; text-decoration: none; border-radius: 4px; margin-top: 20px; cursor: pointer; }}
                .button:hover {{ background: #5568d3; }}
            </style>
        </head>
        <body>
            <div class="container">
                <h1>🚫 Acesso Negado</h1>
                <p>Desculpe, você não tem permissão para acessar o Módulo de Inventário.</p>
                <div class="info-box">
                    <strong>ℹ️ Seu Perfil:</strong><br>
                    Função: <strong>{user_role.upper()}</strong><br><br>
                    Este módulo é apenas para a equipa de armazém (Warehouse).<br><br>
                    Se você é membro da equipa de vendas, aceda ao Dashboard de Vendas em vez disso.
                </div>
                <a href="/dashboard" class="button">→ Ir para Vendas</a>
                <a href="/logout" class="button">🚪 Logout</a>
            </div>
        </body>
        </html>
        """, 403
    
    # Check if inventory sheet is configured - if not, show setup guide
    if not INVENTORY_SPREADSHEET_ID:
        setup_html = """
        <!DOCTYPE html>
        <html lang="pt-PT">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Configuração do Inventário</title>
            <style>
                body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: #f5f5f5; margin: 0; }
                .setup-container { max-width: 900px; margin: 40px auto; padding: 40px; background: white; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
                h1 { color: #333; margin-top: 0; }
                h2 { color: #667eea; font-size: 20px; margin-top: 30px; }
                .info-box { background: #f0f7ff; border-left: 4px solid #667eea; padding: 15px; margin: 15px 0; border-radius: 4px; }
                .warning-box { background: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; margin: 15px 0; border-radius: 4px; }
                .success-box { background: #d4edda; border-left: 4px solid #28a745; padding: 15px; margin: 15px 0; border-radius: 4px; }
                code { background: #f4f4f4; padding: 2px 6px; border-radius: 3px; font-family: monospace; }
                .step { margin: 20px 0; padding: 15px; background: #f9f9f9; border-radius: 4px; }
                .step-number { display: inline-block; background: #667eea; color: white; width: 30px; height: 30px; border-radius: 50%; text-align: center; line-height: 30px; margin-right: 10px; font-weight: bold; }
                button { background: #667eea; color: white; border: none; padding: 12px 24px; border-radius: 4px; cursor: pointer; font-size: 16px; margin-top: 10px; }
                button:hover { background: #5568d3; }
                a { color: #667eea; text-decoration: none; }
                a:hover { text-decoration: underline; }
                .back-link { margin-top: 20px; }
            </style>
        </head>
        <body>
            <div class="setup-container">
                <h1>📦 Configuração do Módulo de Inventário</h1>
                
                <div class="warning-box">
                    <strong>⚠️ Não Configurado Ainda</strong><br>
                    O módulo de inventário ainda não está configurado. Siga os passos abaixo para ativar.
                </div>
                
                <h2>3 Passos Simples Para Ativar</h2>
                
                <div class="step">
                    <span class="step-number">1</span>
                    <strong>Criar Google Sheet com os dados do inventário</strong>
                    <div class="info-box">
                        → Vá para <a href="https://sheets.google.com" target="_blank">Google Sheets</a><br>
                        → Criar novo Sheet<br>
                        → Adicionar as 25 colunas de Inventário
                    </div>
                </div>
                
                <div class="step">
                    <span class="step-number">2</span>
                    <strong>Copiar o Sheet ID</strong>
                    <div class="info-box">
                        Na URL do seu sheet: <code>https://docs.google.com/spreadsheets/d/<strong>SHEET-ID-AQUI</strong>/edit</code><br>
                        Copie a parte em negrito
                    </div>
                </div>
                
                <div class="step">
                    <span class="step-number">3</span>
                    <strong>Atualizar app.py</strong>
                    <div class="info-box">
                        Edite <code>app.py</code> linha ~40:<br>
                        <code>INVENTORY_SPREADSHEET_ID = "seu-sheet-id-aqui"</code><br><br>
                        Depois reinicie o Flask
                    </div>
                </div>
                
                <div class="success-box">
                    <strong>✓ Depois disso:</strong><br>
                    O módulo de inventário estará ativo e funcionando!
                </div>
                
                <h2>Mais Informação</h2>
                <p>
                    Para mais detalhes, veja o guia completo:<br>
                    📖 <a href="https://github.com/globalerc/inventory-setup" target="_blank">INVENTORY_SETUP.md</a>
                </p>
                
                <div class="info-box">
                    <strong>Colunas Necessárias (25):</strong><br>
                    Linha, Quantidade em stock, Tipo, Ref, Modelo, Submodelo, Tipo de tampa, Medida, Tipo de Medida, Madeira, Laminado, Cor, Acabamento, Zinco/Inox, Estofo, Tecido, Renda, Conjunto, Asas, Qtd Asas, Cruz/Cristo, Fecho, Acessórios, Extras/Observações, Cliente
                </div>
                
                <div class="back-link">
                    <a href="/dashboard">← Voltar ao Dashboard de Vendas</a>
                </div>
            </div>
        </body>
        </html>
        """
        return setup_html
    
    return render_template('inventory.html', user_role=user_role)

@app.route('/diagnose-sheet', methods=['GET'])
@login_required
def diagnose_sheet():
    """Diagnose sheet access issues"""
    try:
        user_email = normalize_email(session.get('user_email'))
        user_role = get_user_role(user_email)
        
        # Only admin can diagnose
        if user_role not in ['admin', 'comercial']:
            return jsonify({'error': 'Apenas administradores podem fazer diagnóstico'}), 403
        
        # Get credentials
        creds_info = session.get('credentials')
        if not creds_info:
            return jsonify({'error': 'Credenciais não encontradas'}), 401
        
        credentials = Credentials(
            token=creds_info.get('token'),
            refresh_token=creds_info.get('refresh_token'),
            token_uri=creds_info.get('token_uri'),
            client_id=creds_info.get('client_id'),
            client_secret=creds_info.get('client_secret'),
            scopes=creds_info.get('scopes')
        )
        
        results = {'tests': []}
        
        # Test 1: Open spreadsheet
        print("[DIAGNOSE] Test 1: Opening spreadsheet...")
        try:
            gc = gspread.authorize(credentials)
            spreadsheet = gc.open_by_key(INVENTORY_SPREADSHEET_ID)
            results['tests'].append({
                'name': 'Open Spreadsheet',
                'status': '✅ PASS',
                'details': f'Opened: {spreadsheet.title}',
                'url': spreadsheet.url
            })
            print(f"[DIAGNOSE] ✅ Opened: {spreadsheet.title}")
        except Exception as e:
            results['tests'].append({
                'name': 'Open Spreadsheet',
                'status': '❌ FAIL',
                'error': str(e)
            })
            print(f"[DIAGNOSE] ❌ Error: {e}")
            return jsonify(results), 400
        
        # Test 2: List worksheets
        print("[DIAGNOSE] Test 2: Listing worksheets...")
        try:
            worksheets = spreadsheet.worksheets()
            ws_list = [{'title': ws.title, 'rows': ws.row_count, 'cols': ws.col_count} for ws in worksheets]
            results['tests'].append({
                'name': 'List Worksheets',
                'status': '✅ PASS',
                'count': len(worksheets),
                'worksheets': ws_list
            })
            print(f"[DIAGNOSE] ✅ Found {len(worksheets)} worksheets")
        except Exception as e:
            results['tests'].append({
                'name': 'List Worksheets',
                'status': '❌ FAIL',
                'error': str(e)
            })
            print(f"[DIAGNOSE] ❌ Error: {e}")
        
        # Test 3: Check for Inventário sheet
        print("[DIAGNOSE] Test 3: Checking for 'Inventário' sheet...")
        try:
            inv_sheet = spreadsheet.worksheet("Inventário")
            results['tests'].append({
                'name': 'Inventário Sheet',
                'status': '✅ EXISTS',
                'rows': inv_sheet.row_count,
                'cols': inv_sheet.col_count
            })
            print(f"[DIAGNOSE] ✅ 'Inventário' sheet exists")
        except gspread.exceptions.WorksheetNotFound:
            results['tests'].append({
                'name': 'Inventário Sheet',
                'status': 'ℹ️  NOT FOUND',
                'note': 'Will be created'
            })
            print(f"[DIAGNOSE] INFO: 'Inventario' not found - will create")
        except Exception as e:
            results['tests'].append({
                'name': 'Inventário Sheet',
                'status': '❌ ERROR',
                'error': str(e)
            })
            print(f"[DIAGNOSE] ❌ Error: {e}")
        
        # Test 4: Try to add worksheet
        print("[DIAGNOSE] Test 4: Testing add worksheet capability...")
        try:
            test_ws = spreadsheet.add_worksheet(title="TEST_DIAG", rows=10, cols=3)
            spreadsheet.del_worksheet(test_ws)
            results['tests'].append({
                'name': 'Add Worksheet',
                'status': '✅ PASS',
                'note': 'Can add and remove worksheets'
            })
            print(f"[DIAGNOSE] ✅ Can add worksheets")
        except gspread.exceptions.APIError as e:
            error_msg = str(e)
            results['tests'].append({
                'name': 'Add Worksheet',
                'status': '❌ FAIL',
                'error': error_msg,
                'critical': True if 'not supported' in error_msg.lower() else False
            })
            print(f"[DIAGNOSE] ❌ Add worksheet error: {error_msg}")
        except Exception as e:
            results['tests'].append({
                'name': 'Add Worksheet',
                'status': '❌ ERROR',
                'error': str(e)
            })
            print(f"[DIAGNOSE] ❌ Error: {e}")
        
        # Test 5: Try to append row
        print("[DIAGNOSE] Test 5: Testing append row capability...")
        try:
            ws = spreadsheet.sheet1
            ws.append_row(["TEST"])
            ws.delete_rows(len(ws.get_all_values()))
            results['tests'].append({
                'name': 'Append Row',
                'status': '✅ PASS',
                'note': 'Can append and delete rows'
            })
            print(f"[DIAGNOSE] ✅ Can append rows")
        except gspread.exceptions.APIError as e:
            error_msg = str(e)
            results['tests'].append({
                'name': 'Append Row',
                'status': '❌ FAIL',
                'error': error_msg,
                'critical': True if 'not supported' in error_msg.lower() else False
            })
            print(f"[DIAGNOSE] ❌ Append error: {error_msg}")
        except Exception as e:
            results['tests'].append({
                'name': 'Append Row',
                'status': '❌ ERROR',
                'error': str(e)
            })
            print(f"[DIAGNOSE] ❌ Error: {e}")
        
        results['diagnosis'] = 'Sheet is fully functional' if all(t.get('status', '').startswith('✅') or t.get('status', '').startswith('ℹ️') for t in results['tests']) else 'Some issues found'
        results['sheet_id'] = INVENTORY_SPREADSHEET_ID
        
        return jsonify(results)
        
    except Exception as e:
        print(f"[DIAGNOSE] ❌ Unexpected error: {e}")
        import traceback
        traceback.print_exc()
        return jsonify({'error': str(e)}), 500

@app.route('/create-new-inventory-sheet', methods=['GET', 'POST'])
@login_required
def create_new_inventory_sheet():
    """Create a brand new inventory spreadsheet from scratch"""
    try:
        user_email = normalize_email(session.get('user_email'))
        user_role = get_user_role(user_email)
        
        # Only admin can create
        if user_role not in ['admin', 'comercial']:
            return jsonify({'error': 'Apenas administradores podem criar folhas'}), 403
        
        # Get credentials
        creds_info = session.get('credentials')
        if not creds_info:
            return jsonify({'error': 'Credenciais não encontradas'}), 401
        
        credentials = Credentials(
            token=creds_info.get('token'),
            refresh_token=creds_info.get('refresh_token'),
            token_uri=creds_info.get('token_uri'),
            client_id=creds_info.get('client_id'),
            client_secret=creds_info.get('client_secret'),
            scopes=creds_info.get('scopes')
        )
        
        print("[INVENTORY] Creating new spreadsheet...")
        
        try:
            gc = gspread.authorize(credentials)

            # Create the spreadsheet inside the target Drive folder
            drive_service = build('drive', 'v3', credentials=credentials)
            file_metadata = {
                'name': 'Globale RC - Inventário',
                'mimeType': 'application/vnd.google-apps.spreadsheet'
            }
            if INVENTORY_FOLDER_ID:
                file_metadata['parents'] = [INVENTORY_FOLDER_ID]

            created_file = drive_service.files().create(
                body=file_metadata,
                fields='id, webViewLink'
            ).execute()

            sheet_id = created_file['id']
            globals()['INVENTORY_SPREADSHEET_ID'] = sheet_id
            save_inventory_config(sheet_id)

            print(f"[INVENTORY] ✅ Created new sheet in folder: {sheet_id}")

            # Open the new spreadsheet with gspread
            new_sheet = gc.open_by_key(sheet_id)
            worksheet = new_sheet.sheet1
            
            # Add headers
            print("[INVENTORY] Adding headers...")
            worksheet.append_row(INVENTORY_COLUMNS)
            
            # Format header row
            try:
                header_range = f"A1:{chr(64 + len(INVENTORY_COLUMNS))}1"
                worksheet.format(header_range, {
                    'textFormat': {'bold': True},
                    'backgroundColor': {'red': 0.667, 'green': 0.784, 'blue': 0.922}
                })
                print("[INVENTORY] ✅ Headers formatted")
            except:
                print("[INVENTORY] WARNING: Could not format headers")
            
            print(f"[INVENTORY] ✅ New sheet ready: {new_sheet.url}")
            
            return jsonify({
                'success': True,
                'message': f'✅ Nova folha criada com sucesso!',
                'sheet_id': sheet_id,
                'sheet_name': 'Globale RC - Inventário',
                'url': new_sheet.url,
                'active_sheet_id': sheet_id,
                'instructions': [
                    f'Copie o ID: {sheet_id}',
                    'Abra app.py',
                    'Procure por: INVENTORY_SPREADSHEET_ID = ',
                    f'Altere para: INVENTORY_SPREADSHEET_ID = "{sheet_id}"',
                    'Reinicie a aplicação'
                ]
            })
            
        except Exception as e:
            print(f"[INVENTORY] ❌ Error creating sheet: {e}")
            return jsonify({'error': f'Cannot create sheet: {str(e)}'}), 400
        
    except Exception as e:
        print(f"[INVENTORY] ❌ Unexpected error: {e}")
        import traceback
        traceback.print_exc()
        return jsonify({'error': str(e)}), 500

@app.route('/init-inventory-sheet', methods=['GET', 'POST'])
@login_required
def init_inventory_sheet():
    """Initialize/create the inventory Google Sheet - Pragmatic approach that works around restrictions"""
    try:
        user_email = normalize_email(session.get('user_email'))
        user_role = get_user_role(user_email)
        
        # Only admin can initialize
        if user_role not in ['admin', 'comercial']:
            return jsonify({'error': 'Apenas administradores podem criar a folha'}), 403
        
        # Get credentials
        creds_info = session.get('credentials')
        if not creds_info:
            return jsonify({'error': 'Credenciais não encontradas'}), 401
        
        credentials = Credentials(
            token=creds_info.get('token'),
            refresh_token=creds_info.get('refresh_token'),
            token_uri=creds_info.get('token_uri'),
            client_id=creds_info.get('client_id'),
            client_secret=creds_info.get('client_secret'),
            scopes=creds_info.get('scopes')
        )
        
        gc = gspread.authorize(credentials)
        print(f"[INVENTORY] Opening spreadsheet: {INVENTORY_SPREADSHEET_ID}")
        
        # Step 1: Open the spreadsheet
        try:
            spreadsheet = gc.open_by_key(INVENTORY_SPREADSHEET_ID)
            print(f"[INVENTORY] ✅ Opened: {spreadsheet.title}")
        except Exception as e:
            print(f"[INVENTORY] ❌ Cannot open spreadsheet: {e}")
            return jsonify({'error': f'Cannot access sheet: {str(e)}'}), 400
        
        # Step 2: Find or create worksheet
        worksheet = None
        sheet_source = None
        
        # Try to find Inventário sheet first
        try:
            worksheet = spreadsheet.worksheet("Inventário")
            sheet_source = "existing_inventario"
            print("[INVENTORY] ✅ Found 'Inventário' sheet")
        except gspread.exceptions.WorksheetNotFound:
            # Try to find "Inventário" or use sheet1
            print("[INVENTORY] 'Inventário' not found, checking alternatives...")
            
            # Try to add new worksheet
            try:
                worksheet = spreadsheet.add_worksheet(title="Inventário", rows=1000, cols=26)
                sheet_source = "new_inventario"
                print("[INVENTORY] ✅ Created new 'Inventário' sheet")
            except Exception as e:
                # If we can't add worksheet, use sheet1
                print(f"[INVENTORY] Cannot add sheet ({str(e)[:50]}...), using default sheet...")
                try:
                    worksheet = spreadsheet.sheet1
                    sheet_source = "sheet1_fallback"
                    print("[INVENTORY] ✅ Using Sheet1")
                except Exception as e2:
                    print(f"[INVENTORY] ❌ Cannot access any sheet: {e2}")
                    return jsonify({'error': f'Cannot access sheets: {str(e2)}'}), 400
        
        # Step 3: Check and add headers
        print("[INVENTORY] Reading existing data...")
        try:
            existing_data = worksheet.get_all_values()
            has_headers = len(existing_data) > 0
        except Exception as e:
            print(f"[INVENTORY] Warning reading data: {e}, assuming empty...")
            has_headers = False
            existing_data = []
        
        if not has_headers or (len(existing_data) > 0 and existing_data[0] != INVENTORY_COLUMNS):
            print(f"[INVENTORY] Adding headers...")
            try:
                # Clear the sheet first if it has wrong headers
                if has_headers and existing_data[0] != INVENTORY_COLUMNS:
                    print("[INVENTORY] Clearing existing headers...")
                    try:
                        worksheet.clear()
                        print("[INVENTORY] ✅ Sheet cleared")
                    except Exception as e:
                        print(f"[INVENTORY] Could not clear: {e}, appending anyway...")
                
                # Add headers
                worksheet.append_row(INVENTORY_COLUMNS)
                print(f"[INVENTORY] ✅ Added {len(INVENTORY_COLUMNS)} headers")
                status_msg = f"Headers added to {sheet_source}"
                
                # Try to format (but don't fail if it doesn't work)
                try:
                    col_letter = chr(64 + len(INVENTORY_COLUMNS)) if len(INVENTORY_COLUMNS) <= 26 else 'Z'
                    header_range = f"A1:{col_letter}1"
                    worksheet.format(header_range, {
                        'textFormat': {'bold': True},
                        'backgroundColor': {'red': 0.667, 'green': 0.784, 'blue': 0.922}
                    })
                    print("[INVENTORY] ✅ Formatting applied")
                except Exception as e:
                    print(f"[INVENTORY] WARNING: Formatting not supported: {str(e)[:50]}...")
                    status_msg += " (formatting skipped)"
                
            except Exception as e:
                print(f"[INVENTORY] ❌ Error adding headers: {e}")
                return jsonify({'error': f'Cannot add headers: {str(e)}'}), 400
        else:
            print("[INVENTORY] ✅ Headers already present")
            status_msg = f"Headers already configured on {sheet_source}"
        
        print(f"[INVENTORY] ✅ SUCCESS: {status_msg}")
        
        return jsonify({
            'success': True,
            'message': f'✅ Inventário pronto! {status_msg}',
            'sheet': worksheet.title,
            'sheet_type': sheet_source,
            'headers': len(INVENTORY_COLUMNS),
            'url': spreadsheet.url
        })
        
    except Exception as e:
        print(f"[INVENTORY] ❌ Unexpected error: {e}")
        import traceback
        traceback.print_exc()
        return jsonify({'error': f'Unexpected error: {str(e)}'}), 500

@app.route('/get-inventory-data')
@login_required
def get_inventory_data():
    """Fetch inventory data from Google Sheets - REST API endpoint"""
    try:
        user_email = normalize_email(session.get('user_email'))
        user_role = get_user_role(user_email)
        
        # Check access
        if not has_inventory_access(user_role, user_email):
            return jsonify({'error': 'Acesso negado'}), 403
        
        # Check if inventory sheet is configured
        if not INVENTORY_SPREADSHEET_ID:
            return jsonify({
                'error': 'Inventário não configurado',
                'action': 'Por favor visite /init-inventory-sheet para configurar'
            }), 400
        
        # Check cache
        cache_key = f"inventory:{INVENTORY_SPREADSHEET_ID}:{user_email}"
        cached = get_cached_data(cache_key)
        if cached:
            return jsonify(cached)
        
        # Get credentials from session
        creds_info = session.get('credentials')
        if not creds_info:
            return jsonify({'error': 'Credenciais não encontradas. Faça login novamente.'}), 401
        
        # Create credentials object
        credentials = Credentials(
            token=creds_info.get('token'),
            refresh_token=creds_info.get('refresh_token'),
            token_uri=creds_info.get('token_uri'),
            client_id=creds_info.get('client_id'),
            client_secret=creds_info.get('client_secret'),
            scopes=creds_info.get('scopes')
        )
        
        if credentials.expired:
            refresh_request = Request()
            credentials.refresh(refresh_request)
            session['credentials_dict'] = {
                'token': credentials.token,
                'refresh_token': credentials.refresh_token,
                'token_uri': credentials.token_uri,
                'client_id': credentials.client_id,
                'client_secret': credentials.client_secret,
                'scopes': credentials.scopes
            }
        
        # Connect to Google Sheets
        try:
            gc = gspread.authorize(credentials)
            print(f"[INVENTORY] Opening sheet: {INVENTORY_SPREADSHEET_ID}")
            spreadsheet = gc.open_by_key(INVENTORY_SPREADSHEET_ID)
            print(f"[INVENTORY] ✅ Opened: {spreadsheet.title}")
        except gspread.exceptions.APIError as e:
            error_msg = str(e)
            print(f"[INVENTORY] ❌ API Error: {error_msg}")
            
            if "not supported" in error_msg.lower():
                return jsonify({
                    'error': 'Sheet não suportado',
                    'details': 'Este documento não pode ser acessado via API',
                    'action': 'Crie uma nova folha visitando /create-new-inventory-sheet',
                    'troubleshoot': [
                        'O ID pode ser de um Google Form ou Google Doc',
                        'Pode ter permissões especiais que bloqueiam API',
                        'Tente criar uma nova folha em branco'
                    ]
                }), 400
            else:
                return jsonify({'error': f'Sheet API error: {error_msg}'}), 400
        except Exception as e:
            print(f"[INVENTORY] ❌ Error: {e}")
            return jsonify({'error': f'Cannot access sheet: {str(e)}'}), 400
        
        try:
            worksheet = spreadsheet.sheet1
            print("[INVENTORY] ✅ Got sheet1")
        except Exception as e:
            print(f"[INVENTORY] ❌ Cannot get sheet1: {e}")
            return jsonify({'error': f'Cannot read sheet: {str(e)}'}), 400
        
        try:
            # Get all data
            data = worksheet.get_all_records()
            print(f"[INVENTORY] ✅ Read {len(data)} records")
        except Exception as e:
            print(f"[INVENTORY] ❌ Cannot read data: {e}")
            # Return empty inventory if we can't read
            empty_response = {'items': [], 'summary': {'total_items': 0, 'total_quantity': 0}}
            set_cached_data(cache_key, empty_response)
            return jsonify(empty_response)
        
        # Process data - handle 26 columns including Cor Tecido
        inventory_items = []
        for row in data:
            item = {
                'linha': row.get('Linha', ''),
                'quantidade_em_stock': parse_number(row.get('Quantidade em stock', 0)),
                'tipo': row.get('Tipo', ''),
                'ref': row.get('Ref', ''),
                'modelo': row.get('Modelo', ''),
                'submodelo': row.get('Submodelo', ''),
                'tipo_de_tampa': row.get('Tipo de tampa', ''),
                'medida': row.get('Medida', ''),
                'tipo_de_medida': row.get('Tipo de Medida', ''),
                'madeira': row.get('Madeira', ''),
                'laminado': row.get('Laminado', ''),
                'cor': row.get('Cor', ''),
                'acabamento': row.get('Acabamento', ''),
                'zinco_inox': row.get('Zinco/Inox', ''),
                'estofo': row.get('Estofo', ''),
                'tecido': row.get('Tecido', ''),
                'cor_tecido': row.get('Cor Tecido', ''),
                'renda': row.get('Renda', ''),
                'conjunto': row.get('Conjunto', ''),
                'asas': row.get('Asas', ''),
                'qtd_asas': parse_number(row.get('Qtd Asas', 0)),
                'cruz_cristo': row.get('Cruz/Cristo', ''),
                'fecho': row.get('Fecho', ''),
                'acessorios': row.get('Acessórios', ''),
                'extras_observacoes': row.get('Extras/Observações', ''),
                'cliente': row.get('Cliente', '')
            }
            inventory_items.append(item)
        
        # Calculate summary stats
        total_items = len(inventory_items)
        total_quantity = sum(item['quantidade_em_stock'] for item in inventory_items)
        
        response_data = {
            'items': inventory_items,
            'summary': {
                'total_items': total_items,
                'total_quantity': total_quantity
            }
        }
        
        # Cache the result
        set_cached_data(cache_key, response_data)
        
        return jsonify(response_data)
        
    except Exception as e:
        print(f"[INVENTORY] ❌ Unexpected error: {e}")
        import traceback
        traceback.print_exc()
        return jsonify({'error': f'Erro inesperado: {str(e)}'}), 500


@app.route('/download-inventory', methods=['GET'])
@login_required
def download_inventory():
    """Download inventory data as CSV"""
    try:
        user_email = normalize_email(session.get('user_email'))
        user_role = get_user_role(user_email)

        if not has_inventory_access(user_role, user_email):
            return jsonify({'error': 'Acesso negado'}), 403

        if not INVENTORY_SPREADSHEET_ID:
            return jsonify({'error': 'Inventário não configurado'}), 400

        creds_info = session.get('credentials')
        if not creds_info:
            return jsonify({'error': 'Credenciais não encontradas'}), 401

        credentials = Credentials(
            token=creds_info.get('token'),
            refresh_token=creds_info.get('refresh_token'),
            token_uri=creds_info.get('token_uri'),
            client_id=creds_info.get('client_id'),
            client_secret=creds_info.get('client_secret'),
            scopes=creds_info.get('scopes')
        )

        if credentials.expired:
            refresh_request = Request()
            credentials.refresh(refresh_request)

        gc = gspread.authorize(credentials)
        spreadsheet = gc.open_by_key(INVENTORY_SPREADSHEET_ID)
        worksheet = spreadsheet.sheet1

        values = worksheet.get_all_values()
        if not values:
            values = [INVENTORY_COLUMNS]

        output = io.StringIO()
        writer = csv.writer(output)
        writer.writerows(values)

        csv_content = output.getvalue()
        output.close()

        # UTF-8 BOM for Excel compatibility
        csv_with_bom = '\ufeff' + csv_content
        filename = f"inventario_{datetime.now().strftime('%Y%m%d_%H%M')}.csv"

        return Response(
            csv_with_bom,
            mimetype='text/csv; charset=utf-8',
            headers={
                'Content-Disposition': f'attachment; filename={filename}'
            }
        )
    except Exception as e:
        print(f"[INVENTORY] Error downloading inventory: {e}")
        import traceback
        traceback.print_exc()
        return jsonify({'error': str(e)}), 500

@app.route('/set-inventory-spreadsheet', methods=['POST'])
@login_required
def set_inventory_spreadsheet():
    """Set inventory spreadsheet ID (Admin only)"""
    try:
        user_email = normalize_email(session.get('user_email'))
        user_role = get_user_role(user_email)
        
        # Only admins can set this
        if user_role != 'admin':
            return jsonify({'error': 'Apenas administradores podem configurar'}), 403
        
        data = request.json
        spreadsheet_id = data.get('spreadsheet_id', '').strip()
        
        if not spreadsheet_id:
            return jsonify({'error': 'ID da folha é obrigatório'}), 400
        
        # Validate by trying to access it
        try:
            credentials = Credentials.from_authorized_user_info(
                session.get('credentials_dict'),
                scopes=SCOPES
            )
            
            if credentials.expired:
                refresh_request = Request()
                credentials.refresh(refresh_request)
            
            gc = gspread.authorize(credentials)
            spreadsheet = gc.open_by_key(spreadsheet_id)
            
            # Update global variable and persist to local config
            globals()['INVENTORY_SPREADSHEET_ID'] = spreadsheet_id
            save_inventory_config(spreadsheet_id)
            
            # Clear inventory cache
            clear_cache('inventory')
            
            return jsonify({
                'success': True,
                'message': f'✓ ID do Inventário atualizado: {spreadsheet_id}',
                'spreadsheet_id': spreadsheet_id
            })
            
        except Exception as e:
            return jsonify({'error': f'Não consegui acessar a folha: {str(e)}'}), 400
            
    except Exception as e:
        print(f"[INVENTORY] Error setting spreadsheet: {e}")
        return jsonify({'error': str(e)}), 500

@app.route('/add-inventory-item', methods=['POST'])
@login_required
def add_inventory_item():
    """Add new item to inventory or update existing quantity"""
    try:
        user_email = normalize_email(session.get('user_email'))
        user_role = get_user_role(user_email)
        
        # Check access
        if not has_inventory_access(user_role, user_email):
            return jsonify({'error': 'Acesso negado'}), 403
        
        if not INVENTORY_SPREADSHEET_ID:
            return jsonify({'error': 'Inventário não configurado'}), 400
        
        # Get form data
        data = request.json
        
        # Get credentials
        creds_info = session.get('credentials')
        if not creds_info:
            return jsonify({'error': 'Credenciais não encontradas'}), 401
        
        credentials = Credentials(
            token=creds_info.get('token'),
            refresh_token=creds_info.get('refresh_token'),
            token_uri=creds_info.get('token_uri'),
            client_id=creds_info.get('client_id'),
            client_secret=creds_info.get('client_secret'),
            scopes=creds_info.get('scopes')
        )
        
        # Connect to Google Sheets
        gc = gspread.authorize(credentials)
        spreadsheet = gc.open_by_key(INVENTORY_SPREADSHEET_ID)
        worksheet = spreadsheet.sheet1
        
        # Prepare new row data (26 columns including Cor Tecido)
        new_row = [
            data.get('linha', ''),
            data.get('quantidade_em_stock', 0),
            data.get('tipo', ''),
            data.get('ref', ''),
            data.get('modelo', ''),
            data.get('submodelo', ''),
            data.get('tipo_de_tampa', ''),
            data.get('medida', ''),
            data.get('tipo_de_medida', ''),
            data.get('madeira', ''),
            data.get('laminado', ''),
            data.get('cor', ''),
            data.get('acabamento', ''),
            data.get('zinco_inox', ''),
            data.get('estofo', ''),
            data.get('tecido', ''),
            data.get('cor_tecido', ''),
            data.get('renda', ''),
            data.get('conjunto', ''),
            data.get('asas', ''),
            data.get('qtd_asas', 0),
            data.get('cruz_cristo', ''),
            data.get('fecho', ''),
            data.get('acessorios', ''),
            data.get('extras_observacoes', ''),
            data.get('cliente', '')
        ]
        
        # Append row
        worksheet.append_row(new_row)
        
        # Clear cache
        cache_key = f"inventory:{INVENTORY_SPREADSHEET_ID}:{user_email}"
        clear_cached_data(cache_key)
        
        return jsonify({'success': True, 'message': 'Produto adicionado com sucesso'})
        
    except Exception as e:
        print(f"[INVENTORY] Error adding item: {e}")
        import traceback
        traceback.print_exc()
        return jsonify({'error': str(e)}), 500

@app.route('/remove-inventory-item', methods=['POST'])
@login_required
def remove_inventory_item():
    """Remove or decrease quantity of inventory item"""
    try:
        user_email = normalize_email(session.get('user_email'))
        user_role = get_user_role(user_email)
        
        #Check access
        if not has_inventory_access(user_role, user_email):
            return jsonify({'error': 'Acesso negado'}), 403
        
        if not INVENTORY_SPREADSHEET_ID:
            return jsonify({'error': 'Inventário não configurado'}), 400
        
        data = request.json
        linha = data.get('linha', '')
        quantidade_remover = int(data.get('quantidade', 1))
        
        # Get credentials
        creds_info = session.get('credentials')
        if not creds_info:
            return jsonify({'error': 'Credenciais não encontradas'}), 401
        
        credentials = Credentials(
            token=creds_info.get('token'),
            refresh_token=creds_info.get('refresh_token'),
            token_uri=creds_info.get('token_uri'),
            client_id=creds_info.get('client_id'),
            client_secret=creds_info.get('client_secret'),
            scopes=creds_info.get('scopes')
        )
        
        # Connect to Google Sheets
        gc = gspread.authorize(credentials)
        spreadsheet = gc.open_by_key(INVENTORY_SPREADSHEET_ID)
        worksheet = spreadsheet.sheet1
        
        # Find the row with matching Linha
        all_data = worksheet.get_all_records()
        
        row_index = None
        for idx, row in enumerate(all_data, start=2):  # Start at 2 (row 1 is header)
            if str(row.get('Linha', '')).strip() == str(linha).strip():
                row_index = idx
                current_qty = int(row.get('Quantidade em stock', 0))
                break
        
        if row_index is None:
            return jsonify({'error': 'Produto não encontrado'}), 404
        
        # Calculate new quantity
        new_qty = max(0, current_qty - quantidade_remover)
        
        # Update the quantity column (column B, index 2)
        worksheet.update_cell(row_index, 2, new_qty)
        
        # Clear cache
        cache_key = f"inventory:{INVENTORY_SPREADSHEET_ID}:{user_email}"
        clear_cached_data(cache_key)
        
        return jsonify({
            'success': True,
            'message': f'Quantidade atualizada: {current_qty} → {new_qty}',
            'new_quantity': new_qty
        })
        
    except Exception as e:
        print(f"[INVENTORY] Error removing item: {e}")
        import traceback
        traceback.print_exc()
        return jsonify({'error': str(e)}), 500

@app.route('/update-inventory-position', methods=['POST'])
@login_required
def update_inventory_position():
    """Update item position/location"""
    try:
        user_email = normalize_email(session.get('user_email'))
        user_role = get_user_role(user_email)
        
        if not has_inventory_access(user_role, user_email):
            return jsonify({'error': 'Acesso negado'}), 403
        
        if not INVENTORY_SPREADSHEET_ID:
            return jsonify({'error': 'Inventário não configurado'}), 400
        
        data = request.json
        linha = data.get('linha', '')
        position = data.get('position', '')
        
        # Get credentials
        creds_info = session.get('credentials')
        if not creds_info:
            return jsonify({'error': 'Credenciais não encontradas'}), 401
        
        credentials = Credentials(
            token=creds_info.get('token'),
            refresh_token=creds_info.get('refresh_token'),
            token_uri=creds_info.get('token_uri'),
            client_id=creds_info.get('client_id'),
            client_secret=creds_info.get('client_secret'),
            scopes=creds_info.get('scopes')
        )
        
        # Connect to Google Sheets
        gc = gspread.authorize(credentials)
        spreadsheet = gc.open_by_key(INVENTORY_SPREADSHEET_ID)
        worksheet = spreadsheet.sheet1
        
        # Find the row
        all_data = worksheet.get_all_records()
        
        row_index = None
        for idx, row in enumerate(all_data, start=2):
            if str(row.get('Linha', '')).strip() == str(linha).strip():
                row_index = idx
                break
        
        if row_index is None:
            return jsonify({'error': 'Produto não encontrado'}), 404
        
        # Update Linha column (column A) with position info
        worksheet.update_cell(row_index, 1, position)
        
        # Clear cache
        cache_key = f"inventory:{INVENTORY_SPREADSHEET_ID}:{user_email}"
        clear_cached_data(cache_key)
        
        return jsonify({'success': True, 'message': 'Posição atualizada'})
        
    except Exception as e:
        print(f"[INVENTORY] Error updating position: {e}")
        import traceback
        traceback.print_exc()
        return jsonify({'error': str(e)}), 500


@app.route('/update-inventory-quantity', methods=['POST'])
@login_required
def update_inventory_quantity():
    """Update item quantity via QR scan"""
    try:
        user_email = normalize_email(session.get('user_email'))
        user_role = get_user_role(user_email)
        
        if not has_inventory_access(user_role, user_email):
            return jsonify({'error': 'Acesso negado'}), 403
        
        if not INVENTORY_SPREADSHEET_ID:
            return jsonify({'error': 'Inventário não configurado'}), 400
        
        linha = request.form.get('linha', '')
        ref = request.form.get('ref', '')
        quantidade = int(request.form.get('quantidade', 1))
        
        # Get credentials
        creds_info = session.get('credentials')
        if not creds_info:
            return jsonify({'error': 'Credenciais não encontradas'}), 401
        
        credentials = Credentials(
            token=creds_info.get('token'),
            refresh_token=creds_info.get('refresh_token'),
            token_uri=creds_info.get('token_uri'),
            client_id=creds_info.get('client_id'),
            client_secret=creds_info.get('client_secret'),
            scopes=creds_info.get('scopes')
        )
        
        # Connect to Google Sheets
        gc = gspread.authorize(credentials)
        spreadsheet = gc.open_by_key(INVENTORY_SPREADSHEET_ID)
        worksheet = spreadsheet.sheet1
        
        # Find the row by Linha and Ref
        all_data = worksheet.get_all_records()
        
        row_index = None
        for idx, row in enumerate(all_data, start=2):
            if (str(row.get('Linha', '')).strip() == str(linha).strip() and 
                str(row.get('Ref', '')).strip() == str(ref).strip()):
                row_index = idx
                break
        
        if row_index is None:
            return jsonify({'error': 'Produto não encontrado'}), 404
        
        # Get current quantity and update
        current_qty = int(all_data[row_index - 2].get('Quantidade em stock', 0))
        new_qty = current_qty + quantidade
        
        # Update Quantidade em stock column (column B)
        worksheet.update_cell(row_index, 2, new_qty)
        
        # Clear cache
        cache_key = f"inventory:{INVENTORY_SPREADSHEET_ID}:{user_email}"
        clear_cached_data(cache_key)
        
        return jsonify({'success': True, 'message': f'Quantidade atualizada para {new_qty}', 'new_quantity': new_qty})
        
    except Exception as e:
        print(f"[INVENTORY] Error updating quantity: {e}")
        import traceback
        traceback.print_exc()
        return jsonify({'error': str(e)}), 500

# ============================================================================
# AUTOMATED REPORTING SYSTEM
# ============================================================================

REPORTS_LOG_FILE = "reports_log.json"

def load_reports_log():
    """Load the logs of previously sent reports"""
    if not os.path.exists(REPORTS_LOG_FILE):
        return {
            'weekly_visits': None,
            'monthly_sales': None,
            'monthly_visits': None,
            'quarterly_sales': None,
            'quarterly_visits': None,
            'semi_annual_sales': None,
            'semi_annual_visits': None,
            'yearly_sales': None,
            'yearly_visits': None
        }
    try:
        with open(REPORTS_LOG_FILE, 'r') as f:
            return json.load(f)
    except Exception as e:
        print(f"[REPORTS] Error loading log: {e}")
        return {
            'weekly_visits': None,
            'monthly_sales': None,
            'monthly_visits': None,
            'quarterly_sales': None,
            'quarterly_visits': None,
            'semi_annual_sales': None,
            'semi_annual_visits': None,
            'yearly_sales': None,
            'yearly_visits': None
        }

def save_reports_log(log):
    """Save the reports log"""
    try:
        with open(REPORTS_LOG_FILE, 'w') as f:
            json.dump(log, f, indent=2)
    except Exception as e:
        print(f"[REPORTS] Error saving log: {e}")

def get_sales_summary(days=7):
    """Get sales summary for the last N days"""
    try:
        creds = get_google_credentials()
        if not creds:
            return None
        
        SPREADSHEET_ID = DEFAULT_SPREADSHEET_ID
        gc = gspread.authorize(creds)
        spreadsheet = gc.open_by_key(SPREADSHEET_ID)
        worksheet = spreadsheet.worksheet('BASE')
        
        if not worksheet:
            return None
        
        data = worksheet.get_all_records()
        if not data:
            return None
        
        df = pd.DataFrame(data)
        
        # Parse Mês column and filter by date
        df['Date'] = pd.to_datetime(df.get('Mês', ''), format='%d/%m/%Y', errors='coerce')
        start_date = datetime.now() - timedelta(days=days)
        df_filtered = df[df['Date'] >= start_date]
        
        if df_filtered.empty:
            return {
                'period_days': days,
                'total_sales': 0,
                'top_comercials': [],
                'top_clients': [],
                'by_family': {}
            }
        
        # Parse sales amounts
        df_filtered['Amount'] = df_filtered['Faturaçao'].str.replace('€', '').str.replace(',', '.').str.replace('\xa0', '').astype(float, errors='ignore')
        total_sales = df_filtered['Amount'].sum()
        
        # Top comercials
        top_comercials = df_filtered.groupby('Comercial')['Amount'].sum().sort_values(ascending=False).head(5)
        
        # Top clients
        top_clients = df_filtered.groupby('Cliente')['Amount'].sum().sort_values(ascending=False).head(5)
        
        # By family
        by_family = df_filtered.groupby('Familia')['Amount'].sum().sort_values(ascending=False).to_dict()
        
        return {
            'period_days': days,
            'total_sales': round(total_sales, 2),
            'top_comercials': [(name, round(amount, 2)) for name, amount in top_comercials.items()],
            'top_clients': [(name, round(amount, 2)) for name, amount in top_clients.items()],
            'by_family': {k: round(v, 2) for k, v in by_family.items()}
        }
    except Exception as e:
        print(f"[REPORTS] Error getting sales summary: {e}")
        return None

def get_objectives_performance():
    """Get performance vs objectives"""
    try:
        df_objectives = fetch_objectives()
        if df_objectives is None or df_objectives.empty:
            return None
        
        result = []
        for _, row in df_objectives.iterrows():
            comercial = row.get('Comercial')
            objective = float(str(row.get('Valor Objetivo', 0)).replace('€', '').replace(',', '.').replace('\xa0', '') or 0)
            result.append({
                'comercial': comercial,
                'objective': round(objective, 2)
            })
        
        return result if result else None
    except Exception as e:
        print(f"[REPORTS] Error getting objectives: {e}")
        return None

def get_visit_reports_summary(days=7):
    """Get visit reports summary for the last N days"""
    try:
        creds = get_google_credentials()
        if not creds:
            return None
        
        SPREADSHEET_ID = DEFAULT_SPREADSHEET_ID
        gc = gspread.authorize(creds)
        spreadsheet = gc.open_by_key(SPREADSHEET_ID)
        
        # Find Visit Reports sheet
        worksheet = None
        for sheet in spreadsheet.worksheets():
            if sheet.title.lower() == 'visit reports':
                worksheet = sheet
                break
        
        if not worksheet:
            return None
        
        data = worksheet.get_all_records()
        if not data:
            return {
                'period_days': days,
                'total_visits': 0,
                'by_comercial': {},
                'by_status': {},
                'upcoming_followups': []
            }
        
        df = pd.DataFrame(data)
        
        # Parse dates
        df['VisitDate'] = pd.to_datetime(df.get('Data Visita', ''), format='%d/%m/%Y', errors='coerce')
        df['FollowupDate'] = pd.to_datetime(df.get('Data Seguimento', ''), format='%d/%m/%Y', errors='coerce')
        
        # Filter by date range
        start_date = datetime.now() - timedelta(days=days)
        df_filtered = df[df['VisitDate'] >= start_date]
        
        total_visits = len(df_filtered)
        
        # By comercial
        by_comercial = df_filtered.groupby('Comercial').size().to_dict()
        
        # By status
        by_status = df_filtered.groupby('Estado').size().to_dict()
        
        # Upcoming follow-ups (next 30 days)
        future_date = datetime.now() + timedelta(days=30)
        upcoming = df[(df['FollowupDate'] >= datetime.now()) & (df['FollowupDate'] <= future_date)]
        upcoming_followups = []
        for _, row in upcoming.iterrows():
            upcoming_followups.append({
                'client': row.get('Cliente', ''),
                'comercial': row.get('Comercial', ''),
                'date': row['FollowupDate'].strftime('%d/%m/%Y') if pd.notna(row['FollowupDate']) else '',
                'status': row.get('Estado', '')
            })
        
        return {
            'period_days': days,
            'total_visits': total_visits,
            'by_comercial': by_comercial,
            'by_status': by_status,
            'upcoming_followups': upcoming_followups[:10]  # Limit to 10
        }
    except Exception as e:
        print(f"[REPORTS] Error getting visit reports: {e}")
        return None

def send_report_email(report_type, subject, html_body, recipient_email):
    """Send a report email"""
    if not SMTP_ENABLED or not SMTP_USERNAME or not SMTP_PASSWORD:
        print(f"[REPORTS] SMTP not configured")
        return False
    
    try:
        msg = MIMEMultipart('alternative')
        msg['From'] = SMTP_USERNAME
        msg['To'] = recipient_email
        msg['Subject'] = subject
        msg.attach(MIMEText(html_body, 'html'))
        
        with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
            server.starttls()
            server.login(SMTP_USERNAME, SMTP_PASSWORD)
            server.sendmail(SMTP_USERNAME, [recipient_email], msg.as_string())
        
        print(f"[REPORTS] {report_type} report sent to {recipient_email}")
        return True
    except Exception as e:
        print(f"[REPORTS] Error sending {report_type} report: {e}")
        return False

def generate_weekly_visits_report():
    """Generate and send weekly visit reports (sent every Monday)"""
    today = datetime.now()
    last_report = load_reports_log().get('weekly_visits')
    
    # Send on Monday
    if today.weekday() != 0:
        return
    
    # Check if already sent this week
    if last_report:
        last_date = datetime.fromisoformat(last_report)
        if (today - last_date).days < 7:
            return
    
    summary = get_visit_reports_summary(days=7)
    if not summary:
        return
    
    # Build HTML lists
    by_comercial_html = "<p style='color: #999;'>Sem dados</p>"
    if summary['by_comercial']:
        items = ''.join([f"<li style='margin: 5px 0;'>{name}: {count} visitas</li>" for name, count in summary['by_comercial'].items()])
        by_comercial_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
    
    by_status_html = "<p style='color: #999;'>Sem dados</p>"
    if summary['by_status']:
        items = ''.join([f"<li style='margin: 5px 0;'>{status}: {count}</li>" for status, count in summary['by_status'].items()])
        by_status_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
    
    upcoming_html = "<p style='color: #999;'>Nenhum seguimento agendado</p>"
    if summary['upcoming_followups']:
        items = ''.join([f"<li style='margin: 5px 0;'><strong>{f['client']}</strong> ({f['comercial']}) - {f['date']}</li>" for f in summary['upcoming_followups']])
        upcoming_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
    
    html = f"""
    <html>
        <body style="font-family: Arial, sans-serif; background-color: #f5f5f5; padding: 20px;">
            <div style="max-width: 600px; margin: 0 auto; background-color: white; padding: 20px; border-radius: 10px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
                <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 20px; border-radius: 10px; margin-bottom: 20px;">
                    <h1 style="color: white; margin: 0; font-size: 24px;">📋 Relatório Semanal - Visitas</h1>
                    <p style="color: rgba(255,255,255,0.9); margin: 5px 0 0 0; font-size: 14px;">{today.strftime('%d de %B de %Y')}</p>
                </div>
                
                <div style="padding: 20px 0;">
                    <h2 style="color: #333; font-size: 18px; border-bottom: 2px solid #667eea; padding-bottom: 10px;">Total de Visitas</h2>
                    <p style="font-size: 28px; color: #667eea; font-weight: bold; margin: 10px 0;">{summary['total_visits']}</p>
                    <p style="color: #666; font-size: 14px;">Período: últimos 7 dias</p>
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">Visitas por Comercial</h3>
                    {by_comercial_html}
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">Estado das Visitas</h3>
                    {by_status_html}
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">⏰ Próximos Seguimentos (30 dias)</h3>
                    {upcoming_html}
                </div>
                
                <div style="padding: 20px; margin-top: 20px; background-color: #f9f9f9; border-radius: 8px; border-left: 4px solid #667eea;">
                    <p style="color: #666; font-size: 12px; margin: 0;">
                        Este é um relatório automático do Sales Dashboard Globale RC<br>
                        Enviado em {datetime.now().strftime('%d/%m/%Y às %H:%M')}
                    </p>
                </div>
            </div>
        </body>
    </html>
    """
    
    success = send_report_email('weekly_visits', 'Globale RC: 📋 Relatório Semanal de Visitas', html, SMTP_USERNAME)
    
    if success:
        log = load_reports_log()
        log['weekly_visits'] = datetime.now().isoformat()
        save_reports_log(log)

def generate_weekly_report():
    """DEPRECATED: Weekly sales report - only use for manual testing. 
    Automatic weekly reports are for visits only."""
    today = datetime.now()
    
    summary = get_sales_summary(days=7)
    if not summary:
        return
    
    # Build HTML lists separately
    top_comercials_html = "<p style='color: #999;'>Sem dados</p>"
    if summary['top_comercials']:
        items = ''.join([f"<li style='margin: 5px 0;'>{name}: €{amount:,.2f}</li>" for name, amount in summary['top_comercials']])
        top_comercials_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
    
    top_clients_html = "<p style='color: #999;'>Sem dados</p>"
    if summary['top_clients']:
        items = ''.join([f"<li style='margin: 5px 0;'>{name}: €{amount:,.2f}</li>" for name, amount in summary['top_clients']])
        top_clients_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
    
    html = f"""
    <html>
        <body style="font-family: Arial, sans-serif; background-color: #f5f5f5; padding: 20px;">
            <div style="max-width: 600px; margin: 0 auto; background-color: white; padding: 20px; border-radius: 10px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
                <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 20px; border-radius: 10px; margin-bottom: 20px;">
                    <h1 style="color: white; margin: 0; font-size: 24px;">📊 Relatório Semanal - Vendas</h1>
                    <p style="color: rgba(255,255,255,0.9); margin: 5px 0 0 0; font-size: 14px;">{today.strftime('%d de %B de %Y')}</p>
                </div>
                
                <div style="padding: 20px 0;">
                    <h2 style="color: #333; font-size: 18px; border-bottom: 2px solid #667eea; padding-bottom: 10px;">Vendas Totais</h2>
                    <p style="font-size: 28px; color: #667eea; font-weight: bold; margin: 10px 0;">€{summary['total_sales']:,.2f}</p>
                    <p style="color: #666; font-size: 14px;">Período: últimos 7 dias</p>
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">Top 5 Comerciais</h3>
                    {top_comercials_html}
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">Top 5 Clientes</h3>
                    {top_clients_html}
                </div>
                
                <div style="padding: 20px; margin-top: 20px; background-color: #f9f9f9; border-radius: 8px; border-left: 4px solid #667eea;">
                    <p style="color: #666; font-size: 12px; margin: 0;">
                        Este é um relatório automático do Sales Dashboard Globale RC<br>
                        Enviado em {datetime.now().strftime('%d/%m/%Y às %H:%M')}
                    </p>
                </div>
            </div>
        </body>
    </html>
    """
    
    success = send_report_email('weekly_sales', 'Globale RC: 📊 Relatório Semanal de Vendas', html, SMTP_USERNAME)
    return success

def generate_monthly_sales_report():
    """Generate and send monthly sales report"""
    today = datetime.now()
    last_report = load_reports_log().get('monthly_sales')
    
    # Send on 1st of month
    if today.day != 1:
        return
    
    # Check if already sent this month
    if last_report:
        last_date = datetime.fromisoformat(last_report)
        if last_date.month == today.month and last_date.year == today.year:
            return
    
    summary = get_sales_summary(days=30)
    if not summary:
        return
    
    # Build HTML lists separately
    top_comercials_html = "<p style='color: #999;'>Sem dados</p>"
    if summary['top_comercials']:
        items = ''.join([f"<li style='margin: 5px 0;'>{name}: €{amount:,.2f}</li>" for name, amount in summary['top_comercials']])
        top_comercials_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
    
    by_family_html = "<p style='color: #999;'>Sem dados</p>"
    if summary['by_family']:
        items = ''.join([f"<li style='margin: 5px 0;'>{name}: €{amount:,.2f}</li>" for name, amount in sorted(summary['by_family'].items(), key=lambda x: x[1], reverse=True)[:10]])
        by_family_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
    
    html = f"""
    <html>
        <body style="font-family: Arial, sans-serif; background-color: #f5f5f5; padding: 20px;">
            <div style="max-width: 600px; margin: 0 auto; background-color: white; padding: 20px; border-radius: 10px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
                <div style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); padding: 20px; border-radius: 10px; margin-bottom: 20px;">
                    <h1 style="color: white; margin: 0; font-size: 24px;">📈 Relatório Mensal - Vendas</h1>
                    <p style="color: rgba(255,255,255,0.9); margin: 5px 0 0 0; font-size: 14px;">{today.strftime('%B de %Y')}</p>
                </div>
                
                <div style="padding: 20px 0;">
                    <h2 style="color: #333; font-size: 18px; border-bottom: 2px solid #f5576c; padding-bottom: 10px;">Vendas Totais</h2>
                    <p style="font-size: 28px; color: #f5576c; font-weight: bold; margin: 10px 0;">€{summary['total_sales']:,.2f}</p>
                    <p style="color: #666; font-size: 14px;">Período: últimos 30 dias</p>
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">Top 5 Comerciais</h3>
                    {top_comercials_html}
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">Distribuição por Família</h3>
                    {by_family_html}
                </div>
                
                <div style="padding: 20px; margin-top: 20px; background-color: #f9f9f9; border-radius: 8px; border-left: 4px solid #f5576c;">
                    <p style="color: #666; font-size: 12px; margin: 0;">
                        Este é um relatório automático do Sales Dashboard Globale RC<br>
                        Enviado em {datetime.now().strftime('%d/%m/%Y às %H:%M')}
                    </p>
                </div>
            </div>
        </body>
    </html>
    """
    
    success = send_report_email('monthly_sales', 'Globale RC: 📈 Relatório Mensal de Vendas', html, SMTP_USERNAME)
    
    if success:
        log = load_reports_log()
        log['monthly_sales'] = datetime.now().isoformat()
        save_reports_log(log)

def generate_monthly_visits_report():
    """Generate and send monthly visit reports"""
    today = datetime.now()
    last_report = load_reports_log().get('monthly_visits')
    
    # Send on 1st of month
    if today.day != 1:
        return
    
    # Check if already sent this month
    if last_report:
        last_date = datetime.fromisoformat(last_report)
        if last_date.month == today.month and last_date.year == today.year:
            return
    
    summary = get_visit_reports_summary(days=30)
    if not summary:
        return
    
    # Build HTML lists
    by_comercial_html = "<p style='color: #999;'>Sem dados</p>"
    if summary['by_comercial']:
        items = ''.join([f"<li style='margin: 5px 0;'>{name}: {count} visitas</li>" for name, count in summary['by_comercial'].items()])
        by_comercial_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
    
    by_status_html = "<p style='color: #999;'>Sem dados</p>"
    if summary['by_status']:
        items = ''.join([f"<li style='margin: 5px 0;'>{status}: {count}</li>" for status, count in summary['by_status'].items()])
        by_status_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
    
    html = f"""
    <html>
        <body style="font-family: Arial, sans-serif; background-color: #f5f5f5; padding: 20px;">
            <div style="max-width: 600px; margin: 0 auto; background-color: white; padding: 20px; border-radius: 10px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
                <div style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); padding: 20px; border-radius: 10px; margin-bottom: 20px;">
                    <h1 style="color: white; margin: 0; font-size: 24px;">📋 Relatório Mensal - Visitas</h1>
                    <p style="color: rgba(255,255,255,0.9); margin: 5px 0 0 0; font-size: 14px;">{today.strftime('%B de %Y')}</p>
                </div>
                
                <div style="padding: 20px 0;">
                    <h2 style="color: #333; font-size: 18px; border-bottom: 2px solid #f5576c; padding-bottom: 10px;">Total de Visitas</h2>
                    <p style="font-size: 28px; color: #f5576c; font-weight: bold; margin: 10px 0;">{summary['total_visits']}</p>
                    <p style="color: #666; font-size: 14px;">Período: últimos 30 dias</p>
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">Visitas por Comercial</h3>
                    {by_comercial_html}
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">Estado das Visitas</h3>
                    {by_status_html}
                </div>
                
                <div style="padding: 20px; margin-top: 20px; background-color: #f9f9f9; border-radius: 8px; border-left: 4px solid #f5576c;">
                    <p style="color: #666; font-size: 12px; margin: 0;">
                        Este é um relatório automático do Sales Dashboard Globale RC<br>
                        Enviado em {datetime.now().strftime('%d/%m/%Y às %H:%M')}
                    </p>
                </div>
            </div>
        </body>
    </html>
    """
    
    success = send_report_email('monthly_visits', 'Globale RC: 📋 Relatório Mensal de Visitas', html, SMTP_USERNAME)
    
    if success:
        log = load_reports_log()
        log['monthly_visits'] = datetime.now().isoformat()
        save_reports_log(log)

def generate_quarterly_sales_report():
    """Generate and send quarterly sales report (called after Excel update)"""
    log = load_reports_log()
    last_report = log.get('quarterly_sales')
    
    # Check if already sent this quarter
    today = datetime.now()
    if last_report:
        last_date = datetime.fromisoformat(last_report)
        if (today.year == last_date.year and 
            (today.month - 1) // 3 == (last_date.month - 1) // 3):
            return False
    
    summary = get_sales_summary(days=90)
    performance = get_objectives_performance()
    
    # Build HTML lists
    top_comercials_html = "<p style='color: #999;'>Sem dados</p>"
    if summary and summary['top_comercials']:
        items = ''.join([f"<li style='margin: 5px 0;'>{name}: €{amount:,.2f}</li>" for name, amount in summary['top_comercials']])
        top_comercials_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
    
    objectives_html = "<p style='color: #999;'>Sem dados</p>"
    if performance:
        items = ''.join([f"<li style='margin: 8px 0;'><strong>{p['comercial']}</strong>: €{p['objective']:,.2f}</li>" for p in performance])
        objectives_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
    
    html = f"""
    <html>
        <body style="font-family: Arial, sans-serif; background-color: #f5f5f5; padding: 20px;">
            <div style="max-width: 600px; margin: 0 auto; background-color: white; padding: 20px; border-radius: 10px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
                <div style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); padding: 20px; border-radius: 10px; margin-bottom: 20px;">
                    <h1 style="color: white; margin: 0; font-size: 24px;">📊 Relatório Trimestral - Vendas</h1>
                    <p style="color: rgba(255,255,255,0.9); margin: 5px 0 0 0; font-size: 14px;">Q{(today.month - 1) // 3 + 1} {today.year}</p>
                </div>
                
                <div style="padding: 20px 0;">
                    <h2 style="color: #333; font-size: 18px; border-bottom: 2px solid #4facfe; padding-bottom: 10px;">Vendas Totais</h2>
                    <p style="font-size: 28px; color: #4facfe; font-weight: bold; margin: 10px 0;">€{summary['total_sales'] if summary else 0:,.2f}</p>
                    <p style="color: #666; font-size: 14px;">Período: últimos 90 dias</p>
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">Top Comerciais (Trimestre)</h3>
                    {top_comercials_html}
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">Objetivos</h3>
                    {objectives_html}
                </div>
                
                <div style="padding: 20px; margin-top: 20px; background-color: #f9f9f9; border-radius: 8px; border-left: 4px solid #4facfe;">
                    <p style="color: #666; font-size: 12px; margin: 0;">
                        Este é um relatório automático do Sales Dashboard Globale RC<br>
                        Enviado em {datetime.now().strftime('%d/%m/%Y às %H:%M')}
                    </p>
                </div>
            </div>
        </body>
    </html>
    """
    
    success = send_report_email('quarterly_sales', 'Globale RC: 📊 Relatório Trimestral de Vendas', html, SMTP_USERNAME)
    
    if success:
        log['quarterly_sales'] = datetime.now().isoformat()
        save_reports_log(log)
    return success

def generate_quarterly_visits_report():
    """Generate and send quarterly visit reports (scheduled)"""
    today = datetime.now()
    last_report = load_reports_log().get('quarterly_visits')
    
    # Send on 1st of Jan, Apr, Jul, Oct
    if today.month not in [1, 4, 7, 10] or today.day != 1:
        return
    
    # Check if already sent this quarter
    if last_report:
        last_date = datetime.fromisoformat(last_report)
        if (today.year == last_date.year and 
            (today.month - 1) // 3 == (last_date.month - 1) // 3):
            return
    
    visit_summary = get_visit_reports_summary(days=90)
    
    # Build HTML lists
    by_comercial_html = "<p style='color: #999;'>Sem dados</p>"
    if visit_summary and visit_summary['by_comercial']:
        items = ''.join([f"<li style='margin: 5px 0;'>{name}: {count} visitas</li>" for name, count in visit_summary['by_comercial'].items()])
        by_comercial_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
    
    by_status_html = "<p style='color: #999;'>Sem dados</p>"
    if visit_summary and visit_summary['by_status']:
        items = ''.join([f"<li style='margin: 5px 0;'>{status}: {count}</li>" for status, count in visit_summary['by_status'].items()])
        by_status_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
    
    html = f"""
    <html>
        <body style="font-family: Arial, sans-serif; background-color: #f5f5f5; padding: 20px;">
            <div style="max-width: 600px; margin: 0 auto; background-color: white; padding: 20px; border-radius: 10px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
                <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 20px; border-radius: 10px; margin-bottom: 20px;">
                    <h1 style="color: white; margin: 0; font-size: 24px;">🗓️ Relatório Trimestral - Visitas</h1>
                    <p style="color: rgba(255,255,255,0.9); margin: 5px 0 0 0; font-size: 14px;">Q{(today.month - 1) // 3 + 1} {today.year}</p>
                </div>
                
                <div style="padding: 20px 0;">
                    <h2 style="color: #333; font-size: 18px; border-bottom: 2px solid #667eea; padding-bottom: 10px;">Total de Visitas</h2>
                    <p style="font-size: 28px; color: #667eea; font-weight: bold; margin: 10px 0;">{visit_summary['total_visits'] if visit_summary else 0}</p>
                    <p style="color: #666; font-size: 14px;">Últimos 90 dias</p>
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">Por Comercial</h3>
                    {by_comercial_html}
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">Por Estado</h3>
                    {by_status_html}
                </div>
                
                <div style="padding: 20px; margin-top: 20px; background-color: #f9f9f9; border-radius: 8px; border-left: 4px solid #667eea;">
                    <p style="color: #666; font-size: 12px; margin: 0;">
                        Este é um relatório automático do Sales Dashboard Globale RC<br>
                        Enviado em {datetime.now().strftime('%d/%m/%Y às %H:%M')}
                    </p>
                </div>
            </div>
        </body>
    </html>
    """
    
    success = send_report_email('quarterly_visits', 'Globale RC: 🗓️ Relatório Trimestral de Visitas', html, SMTP_USERNAME)
    
    if success:
        log = load_reports_log()
        log['quarterly_visits'] = datetime.now().isoformat()
        save_reports_log(log)

def generate_semi_annual_sales_report():
    """Generate and send semi-annual sales report (called after Excel update)"""
    log = load_reports_log()
    last_report = log.get('semi_annual_sales')
    
    # Check if already sent this semester
    today = datetime.now()
    if last_report:
        last_date = datetime.fromisoformat(last_report)
        # Same year and same half (Jan-Jun = 0, Jul-Dec = 1)
        if (today.year == last_date.year and 
            (today.month - 1) // 6 == (last_date.month - 1) // 6):
            return False
    
    summary = get_sales_summary(days=180)
    performance = get_objectives_performance()
    
    # Build HTML lists
    top_comercials_html = "<p style='color: #999;'>Sem dados</p>"
    if summary and summary['top_comercials']:
        items = ''.join([f"<li style='margin: 5px 0;'>{name}: €{amount:,.2f}</li>" for name, amount in summary['top_comercials']])
        top_comercials_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
    
    objectives_html = "<p style='color: #999;'>Sem dados</p>"
    if performance:
        items = ''.join([f"<li style='margin: 8px 0;'><strong>{p['comercial']}</strong>: €{p['objective']:,.2f}</li>" for p in performance])
        objectives_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
    
    html = f"""
    <html>
        <body style="font-family: Arial, sans-serif; background-color: #f5f5f5; padding: 20px;">
            <div style="max-width: 600px; margin: 0 auto; background-color: white; padding: 20px; border-radius: 10px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
                <div style="background: linear-gradient(135deg, #fa709a 0%, #fee140 100%); padding: 20px; border-radius: 10px; margin-bottom: 20px;">
                    <h1 style="color: white; margin: 0; font-size: 24px;">💼 Relatório Semestral - Vendas</h1>
                    <p style="color: rgba(255,255,255,0.9); margin: 5px 0 0 0; font-size: 14px;">{'1º Semestre' if today.month <= 6 else '2º Semestre'} {today.year}</p>
                </div>
                
                <div style="padding: 20px 0;">
                    <h2 style="color: #333; font-size: 18px; border-bottom: 2px solid #fa709a; padding-bottom: 10px;">Vendas Totais</h2>
                    <p style="font-size: 28px; color: #fa709a; font-weight: bold; margin: 10px 0;">€{summary['total_sales'] if summary else 0:,.2f}</p>
                    <p style="color: #666; font-size: 14px;">Período: últimos 6 meses</p>
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">Top Comerciais (6 Meses)</h3>
                    {top_comercials_html}
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">Status dos Objetivos</h3>
                    {objectives_html}
                </div>
                
                <div style="padding: 20px; margin-top: 20px; background-color: #f9f9f9; border-radius: 8px; border-left: 4px solid #fa709a;">
                    <p style="color: #666; font-size: 12px; margin: 0;">
                        Este é um relatório automático do Sales Dashboard Globale RC<br>
                        Enviado em {datetime.now().strftime('%d/%m/%Y às %H:%M')}
                    </p>
                </div>
            </div>
        </body>
    </html>
    """
    
    success = send_report_email('semi_annual_sales', 'Globale RC: 💼 Relatório Semestral de Vendas', html, SMTP_USERNAME)
    
    if success:
        log['semi_annual_sales'] = datetime.now().isoformat()
        save_reports_log(log)
    return success

def generate_semi_annual_visits_report():
    """Generate and send semi-annual visit reports (scheduled)"""
    today = datetime.now()
    last_report = load_reports_log().get('semi_annual_visits')
    
    # Send on Jan 1 and Jul 1
    if (today.month not in [1, 7]) or today.day != 1:
        return
    
    # Check if already sent this period
    if last_report:
        last_date = datetime.fromisoformat(last_report)
        if (today.year == last_date.year and today.month == last_date.month):
            return
    
    visit_summary = get_visit_reports_summary(days=180)
    
    # Build HTML lists
    by_comercial_html = "<p style='color: #999;'>Sem dados</p>"
    if visit_summary and visit_summary['by_comercial']:
        items = ''.join([f"<li style='margin: 5px 0;'>{name}: {count} visitas</li>" for name, count in visit_summary['by_comercial'].items()])
        by_comercial_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
    
    by_status_html = "<p style='color: #999;'>Sem dados</p>"
    if visit_summary and visit_summary['by_status']:
        items = ''.join([f"<li style='margin: 5px 0;'>{status}: {count}</li>" for status, count in visit_summary['by_status'].items()])
        by_status_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
    
    html = f"""
    <html>
        <body style="font-family: Arial, sans-serif; background-color: #f5f5f5; padding: 20px;">
            <div style="max-width: 600px; margin: 0 auto; background-color: white; padding: 20px; border-radius: 10px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
                <div style="background: linear-gradient(135deg, #fa709a 0%, #fee140 100%); padding: 20px; border-radius: 10px; margin-bottom: 20px;">
                    <h1 style="color: white; margin: 0; font-size: 24px;">📅 Relatório Semestral - Visitas</h1>
                    <p style="color: rgba(255,255,255,0.9); margin: 5px 0 0 0; font-size: 14px;">{'1º Semestre' if today.month == 1 else '2º Semestre'} {today.year}</p>
                </div>
                
                <div style="padding: 20px 0;">
                    <h2 style="color: #333; font-size: 18px; border-bottom: 2px solid #fa709a; padding-bottom: 10px;">Total de Visitas</h2>
                    <p style="font-size: 28px; color: #fa709a; font-weight: bold; margin: 10px 0;">{visit_summary['total_visits'] if visit_summary else 0}</p>
                    <p style="color: #666; font-size: 14px;">Últimos 6 meses</p>
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">Por Comercial</h3>
                    {by_comercial_html}
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">Por Estado</h3>
                    {by_status_html}
                </div>
                
                <div style="padding: 20px; margin-top: 20px; background-color: #f9f9f9; border-radius: 8px; border-left: 4px solid #fa709a;">
                    <p style="color: #666; font-size: 12px; margin: 0;">
                        Este é um relatório automático do Sales Dashboard Globale RC<br>
                        Enviado em {datetime.now().strftime('%d/%m/%Y às %H:%M')}
                    </p>
                </div>
            </div>
        </body>
    </html>
    """
    
    success = send_report_email('semi_annual_visits', 'Globale RC: 📅 Relatório Semestral de Visitas', html, SMTP_USERNAME)
    
    if success:
        log = load_reports_log()
        log['semi_annual_visits'] = datetime.now().isoformat()
        save_reports_log(log)

def generate_yearly_sales_report():
    """Generate and send yearly sales report (called after Excel update)"""
    log = load_reports_log()
    last_report = log.get('yearly_sales')
    
    # Check if already sent this year
    today = datetime.now()
    if last_report:
        last_date = datetime.fromisoformat(last_report)
        if last_date.year == today.year:
            return False
    
    summary = get_sales_summary(days=365)
    performance = get_objectives_performance()
    
    # Build HTML lists
    top_comercials_html = "<p style='color: #999;'>Sem dados</p>"
    if summary and summary['top_comercials']:
        items = ''.join([f"<li style='margin: 8px 0;'><strong>{name}</strong>: €{amount:,.2f}</li>" for name, amount in summary['top_comercials']])
        top_comercials_html = f"<ol style='margin: 10px 0; padding-left: 25px;'>{items}</ol>"
    
    objectives_html = "<p style='color: #999;'>Sem dados</p>"
    if performance:
        items = ''.join([f"<li style='margin: 8px 0;'><strong>{p['comercial']}</strong><br>Objetivo Anual: €{p['objective']:,.2f}</li>" for p in performance])
        objectives_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
    
    html = f"""
    <html>
        <body style="font-family: Arial, sans-serif; background-color: #f5f5f5; padding: 20px;">
            <div style="max-width: 600px; margin: 0 auto; background-color: white; padding: 20px; border-radius: 10px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
                <div style="background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%); padding: 20px; border-radius: 10px; margin-bottom: 20px;">
                    <h1 style="color: white; margin: 0; font-size: 24px;">🏆 Relatório Anual - Vendas</h1>
                    <p style="color: rgba(255,255,255,0.9); margin: 5px 0 0 0; font-size: 14px;">{today.year}</p>
                </div>
                
                <div style="padding: 20px 0;">
                    <h2 style="color: #333; font-size: 18px; border-bottom: 2px solid #11998e; padding-bottom: 10px;">Vendas Totais Anuais</h2>
                    <p style="font-size: 32px; color: #11998e; font-weight: bold; margin: 10px 0;">€{summary['total_sales'] if summary else 0:,.2f}</p>
                    <p style="color: #666; font-size: 14px;">Período: 365 dias</p>
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">🥇 Top Comerciais do Ano</h3>
                    {top_comercials_html}
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">🎯 Resultados de Objetivos</h3>
                    {objectives_html}
                </div>
                
                <div style="padding: 20px; margin-top: 20px; background-color: #f9f9f9; border-radius: 8px; border-left: 4px solid #11998e;">
                    <p style="color: #666; font-size: 12px; margin: 0;">
                        Este é o relatório automático anual do Sales Dashboard Globale RC<br>
                        Enviado em {datetime.now().strftime('%d/%m/%Y às %H:%M')}
                    </p>
                </div>
            </div>
        </body>
    </html>
    """
    
    success = send_report_email('yearly_sales', 'Globale RC: 🏆 Relatório Anual de Vendas', html, SMTP_USERNAME)
    
    if success:
        log['yearly_sales'] = datetime.now().isoformat()
        save_reports_log(log)
    return success

def generate_yearly_visits_report():
    """Generate and send yearly visit reports (scheduled)"""
    today = datetime.now()
    last_report = load_reports_log().get('yearly_visits')
    
    # Send on Jan 1
    if today.month != 1 or today.day != 1:
        return
    
    # Check if already sent this year
    if last_report:
        last_date = datetime.fromisoformat(last_report)
        if last_date.year == today.year:
            return
    
    visit_summary = get_visit_reports_summary(days=365)
    
    # Build HTML lists
    by_comercial_html = "<p style='color: #999;'>Sem dados</p>"
    if visit_summary and visit_summary['by_comercial']:
        items = ''.join([f"<li style='margin: 8px 0;'><strong>{name}</strong>: {count} visitas</li>" for name, count in visit_summary['by_comercial'].items()])
        by_comercial_html = f"<ol style='margin: 10px 0; padding-left: 25px;'>{items}</ol>"
    
    by_status_html = "<p style='color: #999;'>Sem dados</p>"
    if visit_summary and visit_summary['by_status']:
        items = ''.join([f"<li style='margin: 5px 0;'>{status}: {count}</li>" for status, count in visit_summary['by_status'].items()])
        by_status_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
    
    html = f"""
    <html>
        <body style="font-family: Arial, sans-serif; background-color: #f5f5f5; padding: 20px;">
            <div style="max-width: 600px; margin: 0 auto; background-color: white; padding: 20px; border-radius: 10px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
                <div style="background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%); padding: 20px; border-radius: 10px; margin-bottom: 20px;">
                    <h1 style="color: white; margin: 0; font-size: 24px;">📆 Relatório Anual - Visitas</h1>
                    <p style="color: rgba(255,255,255,0.9); margin: 5px 0 0 0; font-size: 14px;">{today.year}</p>
                </div>
                
                <div style="padding: 20px 0;">
                    <h2 style="color: #333; font-size: 18px; border-bottom: 2px solid #11998e; padding-bottom: 10px;">Total de Visitas Anuais</h2>
                    <p style="font-size: 32px; color: #11998e; font-weight: bold; margin: 10px 0;">{visit_summary['total_visits'] if visit_summary else 0}</p>
                    <p style="color: #666; font-size: 14px;">Período: 365 dias</p>
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">🥇 Top Comerciais do Ano</h3>
                    {by_comercial_html}
                </div>
                
                <div style="padding: 20px 0; border-top: 1px solid #eee;">
                    <h3 style="color: #333; font-size: 16px;">Por Estado</h3>
                    {by_status_html}
                </div>
                
                <div style="padding: 20px; margin-top: 20px; background-color: #f9f9f9; border-radius: 8px; border-left: 4px solid #11998e;">
                    <p style="color: #666; font-size: 12px; margin: 0;">
                        Este é o relatório automático anual do Sales Dashboard Globale RC<br>
                        Enviado em {datetime.now().strftime('%d/%m/%Y às %H:%M')}
                    </p>
                </div>
            </div>
        </body>
    </html>
    """
    
    success = send_report_email('yearly_visits', 'Globale RC: 📆 Relatório Anual de Visitas', html, SMTP_USERNAME)
    
    if success:
        log = load_reports_log()
        log['yearly_visits'] = datetime.now().isoformat()
        save_reports_log(log)

def send_sales_reports_after_update():
    """Send all sales reports after Excel file update (not scheduled)"""
    try:
        if SMTP_ENABLED:
            print("[SALES REPORTS] Sending sales reports after Excel update...")
            generate_monthly_sales_report()
            generate_quarterly_sales_report()
            generate_semi_annual_sales_report()
            generate_yearly_sales_report()
            print("[SALES REPORTS] All sales reports sent")
    except Exception as e:
        print(f"[SALES REPORTS] Error sending sales reports: {e}")

def check_and_send_reports():
    """Check if any VISIT reports need to be sent (scheduled, runs hourly)"""
    try:
        if SMTP_ENABLED:
            # Only scheduled visit reports here - sales reports sent separately on Excel update
            generate_weekly_visits_report()
            generate_monthly_visits_report()
            generate_quarterly_visits_report()
            generate_semi_annual_visits_report()
            generate_yearly_visits_report()
            print("[REPORTS] Visit report check completed")
    except Exception as e:
        print(f"[REPORTS] Error in report check: {e}")

def background_report_checker():
    """Background thread that checks for reports every hour"""
    while True:
        try:
            time.sleep(3600)  # Check every hour
            check_and_send_reports()
        except Exception as e:
            print(f"[REPORTS] Background thread error: {e}")
            time.sleep(3600)

# ============================================================================
# RUN
# ============================================================================

if __name__ == '__main__':
    print("\n" + "="*80)
    print("CLEAN SALES DASHBOARD")
    print("="*80)
    
    # Start background report checker
    if SMTP_ENABLED:
        report_thread = threading.Thread(target=background_report_checker, daemon=True)
        report_thread.start()
        print("[REPORTS] Background report checker started")
    
    # Display server URL
    print(f"Server URL: {SERVER_URL}")
    print(f"Mode: {FLASK_MODE.upper()}")
    print(f"OAuth Redirect URI: {REDIRECT_URI_BASE}")
    print("="*80 + "\n")
    
    # Development uses Flask dev server. Production should use gunicorn + nginx.
    app.run(debug=not IS_PRODUCTION, host=FLASK_HOST, port=FLASK_PORT, use_reloader=(not IS_PRODUCTION))

@app.route("/debug/me")
@login_required
def debug_me():
    return {
        "email": getattr(current_user, "email", None),
        "name": getattr(current_user, "name", None),
        "role": getattr(current_user, "role", None),
        "is_authenticated": current_user.is_authenticated,
    }

@app.route("/debug/send-reports", methods=['GET'])
@login_required
def debug_send_reports():
    """Manual trigger for reports (admin only)"""
    user_email = session.get('user_email')
    if user_email not in ADMIN_EMAILS:
        return jsonify({'error': 'Acesso negado'}), 403
    
    try:
        check_and_send_reports()
        return jsonify({
            'success': True,
            'message': 'Relatórios foram verificados e enviados se necessário',
            'report_log': load_reports_log()
        })
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route("/debug/test-weekly-report", methods=['GET'])
@login_required
def debug_test_weekly_report():
    """Test send a weekly report (admin only)"""
    user_email = session.get('user_email')
    if user_email not in ADMIN_EMAILS:
        return jsonify({'error': 'Acesso negado'}), 403
    
    try:
        summary = get_sales_summary(days=7)
        if not summary:
            return jsonify({'error': 'Não foi possível obter dados de vendas'}), 400
        
        # Build HTML lists separately
        top_comercials_html = "<p style='color: #999;'>Sem dados</p>"
        if summary['top_comercials']:
            items = ''.join([f"<li style='margin: 5px 0;'>{name}: €{amount:,.2f}</li>" for name, amount in summary['top_comercials']])
            top_comercials_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
        
        top_clients_html = "<p style='color: #999;'>Sem dados</p>"
        if summary['top_clients']:
            items = ''.join([f"<li style='margin: 5px 0;'>{name}: €{amount:,.2f}</li>" for name, amount in summary['top_clients']])
            top_clients_html = f"<ul style='margin: 10px 0; padding-left: 20px;'>{items}</ul>"
        
        html = f"""
        <html>
            <body style="font-family: Arial, sans-serif; background-color: #f5f5f5; padding: 20px;">
                <div style="max-width: 600px; margin: 0 auto; background-color: white; padding: 20px; border-radius: 10px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);">
                    <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 20px; border-radius: 10px; margin-bottom: 20px;">
                        <h1 style="color: white; margin: 0; font-size: 24px;">📊 Relatório Semanal - Vendas (TESTE)</h1>
                        <p style="color: rgba(255,255,255,0.9); margin: 5px 0 0 0; font-size: 14px;">{datetime.now().strftime('%d de %B de %Y')}</p>
                    </div>
                    
                    <div style="padding: 20px 0;">
                        <h2 style="color: #333; font-size: 18px; border-bottom: 2px solid #667eea; padding-bottom: 10px;">Vendas Totais</h2>
                        <p style="font-size: 28px; color: #667eea; font-weight: bold; margin: 10px 0;">€{summary['total_sales']:,.2f}</p>
                        <p style="color: #666; font-size: 14px;">Período: últimos 7 dias</p>
                    </div>
                    
                    <div style="padding: 20px 0; border-top: 1px solid #eee;">
                        <h3 style="color: #333; font-size: 16px;">Top 5 Comerciais</h3>
                        {top_comercials_html}
                    </div>
                    
                    <div style="padding: 20px 0; border-top: 1px solid #eee;">
                        <h3 style="color: #333; font-size: 16px;">Top 5 Clientes</h3>
                        {top_clients_html}
                    </div>
                    
                    <div style="padding: 20px; margin-top: 20px; background-color: #f9f9f9; border-radius: 8px; border-left: 4px solid #667eea;">
                        <p style="color: #666; font-size: 12px; margin: 0;">
                            Este é um relatório automático do Sales Dashboard Globale RC<br>
                            Enviado em {datetime.now().strftime('%d/%m/%Y às %H:%M')}
                        </p>
                    </div>
                </div>
            </body>
        </html>
        """
        
        # Try to send
        success = send_report_email('weekly (teste)', 'Globale RC: 📊 Relatório Semanal de Vendas (TESTE)', html, user_email)
        
        return jsonify({
            'success': success,
            'message': 'Email de teste enviado',
            'email': user_email,
            'summary': summary
        })
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@app.route("/debug/send-sales-reports", methods=['GET'])
@login_required
def debug_send_sales_reports():
    """Trigger sales reports after Excel update (admin only)"""
    user_email = session.get('user_email')
    if user_email not in ADMIN_EMAILS:
        return jsonify({'error': 'Acesso negado'}), 403
    
    try:
        send_sales_reports_after_update()
        return jsonify({
            'success': True,
            'message': 'Relatórios de vendas enviados após atualização do Excel',
            'report_log': load_reports_log()
        })
    except Exception as e:
        return jsonify({'error': str(e)}), 500