from datetime import datetime, timedelta
from flask import Blueprint, render_template, request, session, jsonify
from sqlalchemy import func
from ..models import db, Pessoa, Usuario, Campanha
from ..utils.auth_decorators import login_required

territorio_bp = Blueprint('territorio', __name__, url_prefix='/territorio')

COORDS_BAIRROS_MANAUS = {
    'Cidade Nova': [-3.0305, -59.9708],
    'Jorge Teixeira': [-3.0512, -59.9241],
    'Compensa': [-3.1091, -60.0543],
    'Alvorada': [-3.0850, -60.0410],
    'Centro': [-3.1316, -60.0232],
    'São José Operário': [-3.0811, -59.9532],
    'Coroado': [-3.0945, -59.9782],
    'Parque 10 de Novembro': [-3.0832, -60.0089],
    'Flores': [-3.0645, -60.0156],
    'Adrianópolis': [-3.1045, -60.0123],
    'Aleixo': [-3.0988, -59.9950],
    'Japiim': [-3.1150, -59.9850],
    'Armando Mendes': [-3.0889, -59.9388],
    'Nova Cidade': [-3.0080, -59.9850],
    'Novo Aleixo': [-3.0480, -59.9550],
    'Santa Etelvina': [-2.9910, -59.9950],
    'Tarumã': [-3.0350, -60.0850],
    'Dom Pedro': [-3.0920, -60.0380],
    'Glória': [-3.1250, -60.0390],
    'Educandos': [-3.1410, -60.0110]
}

ZONAS_MANAUS = ['Zona Norte', 'Zona Leste', 'Zona Sul', 'Zona Oeste', 'Centro-Sul', 'Centro-Oeste']

@territorio_bp.route('/')
@territorio_bp.route('/mapa')
@login_required
def mapa():
    campanha_id = session.get('campanha_id')
    try:
        campanha = db.session.get(Campanha, campanha_id) if campanha_id else Campanha.query.first()
    except Exception:
        db.create_all()
        from .. import _auto_seed_if_empty
        _auto_seed_if_empty()
        campanha = Campanha.query.first()

    if not campanha:
        campanha = Campanha.query.first()
        if campanha:
            session['campanha_id'] = campanha.id
    
    # 1. Cards no topo
    total_geral = db.session.query(func.count(Pessoa.id)).scalar() or 0
    
    hoje_inicio = datetime.utcnow().replace(hour=0, minute=0, second=0, microsecond=0)
    cadastros_hoje = db.session.query(func.count(Pessoa.id)).filter(
        Pessoa.criado_em >= hoje_inicio
    ).scalar() or 0
    
    mes_inicio = datetime.utcnow().replace(day=1, hour=0, minute=0, second=0, microsecond=0)
    cadastros_mes = db.session.query(func.count(Pessoa.id)).filter(
        Pessoa.criado_em >= mes_inicio
    ).scalar() or 0
    
    bairros_cobertos = db.session.query(func.count(func.distinct(Pessoa.bairro))).scalar() or 0
    
    sem_localizacao = db.session.query(func.count(Pessoa.id)).filter(
        (Pessoa.bairro == None) | (Pessoa.bairro == '')
    ).scalar() or 0

    # 2. Sidebar Cadastros por Zona
    cadastros_por_zona = db.session.query(
        Pessoa.zona, func.count(Pessoa.id).label('total')
    ).group_by(Pessoa.zona).order_by(func.count(Pessoa.id).desc()).all()

    # 3. Sidebar Top 10 Bairros
    top_bairros = db.session.query(
        Pessoa.bairro, Pessoa.zona, func.count(Pessoa.id).label('total')
    ).group_by(Pessoa.bairro, Pessoa.zona).order_by(func.count(Pessoa.id).desc()).limit(10).all()

    cadastradores = Usuario.query.filter_by(perfil=Usuario.ROLE_CADASTRADOR).all()

    return render_template(
        'territorio/mapa.html',
        campanha=campanha,
        total_geral=total_geral,
        cadastros_hoje=cadastros_hoje,
        cadastros_mes=cadastros_mes,
        bairros_cobertos=bairros_cobertos,
        sem_localizacao=sem_localizacao,
        cadastros_por_zona=cadastros_por_zona,
        top_bairros=top_bairros,
        cadastradores=cadastradores,
        zonas=ZONAS_MANAUS
    )

@territorio_bp.route('/api/pontos')
@login_required
def api_pontos():
    """Endpoint para retornar todos os apoiadores cadastrados no mapa com suporte a agrupamento por bairro"""
    cadastrador_id = request.args.get('cadastrador_id')
    zona_filtro = request.args.get('zona')
    bairro_filtro = request.args.get('bairro')
    
    query = Pessoa.query
    
    if cadastrador_id:
        query = query.filter(Pessoa.cadastrador_id == int(cadastrador_id))
    if zona_filtro:
        query = query.filter(Pessoa.zona == zona_filtro)
    if bairro_filtro:
        query = query.filter(Pessoa.bairro == bairro_filtro)
        
    pessoas = query.all()
    
    from ..models import BairroZona
    
    pontos = []
    for p in pessoas:
        lat = p.lat
        lng = p.lng
        
        if lat is None or lng is None:
            base_coords = COORDS_BAIRROS_MANAUS.get(p.bairro)
            if not base_coords:
                bz = BairroZona.query.filter_by(bairro=p.bairro).first()
                if bz and bz.lat and bz.lng:
                    base_coords = [bz.lat, bz.lng]
                else:
                    base_coords = [-3.1000, -60.0200]
                    
            lat_jitter = (((p.id * 17) % 100) - 50) * 0.00014
            lng_jitter = (((p.id * 31) % 100) - 50) * 0.00014
            
            lat = base_coords[0] + lat_jitter
            lng = base_coords[1] + lng_jitter
            
        cadastrador_nome = p.cadastrador.nome if p.cadastrador else 'Não informado'
        data_cad_str = p.criado_em.strftime('%d/%m/%Y') if p.criado_em else 'N/A'

        pontos.append({
            'id': p.id,
            'nome': p.nome_completo,
            'bairro': p.bairro or 'Manaus',
            'zona': p.zona or 'Zona Urbana',
            'lat': lat,
            'lng': lng,
            'cadastrador': cadastrador_nome,
            'data': data_cad_str
        })
        
    return jsonify({'total': len(pontos), 'pontos': pontos})

@territorio_bp.route('/api/dados')
@login_required
def api_dados():
    """Endpoint otimizado para sumarização de estatísticas"""
    cadastrador_id = request.args.get('cadastrador_id')
    zona_filtro = request.args.get('zona')
    bairro_filtro = request.args.get('bairro')
    
    query = db.session.query(
        Pessoa.bairro, Pessoa.zona, func.count(Pessoa.id).label('total')
    )
    
    if cadastrador_id:
        query = query.filter(Pessoa.cadastrador_id == int(cadastrador_id))
        
    if zona_filtro:
        query = query.filter(Pessoa.zona == zona_filtro)
        
    if bairro_filtro:
        query = query.filter(Pessoa.bairro == bairro_filtro)
        
    resultados = query.group_by(Pessoa.bairro, Pessoa.zona).order_by(func.count(Pessoa.id).desc()).all()
    
    bairros_data = []
    total_geral = 0
    
    for r in resultados:
        bairro, zona, total = r[0], r[1], r[2]
        total_geral += total
        coords = COORDS_BAIRROS_MANAUS.get(bairro, [-3.1000, -60.0200])
        bairros_data.append({
            'bairro': bairro,
            'zona': zona,
            'total': total,
            'lat': coords[0],
            'lng': coords[1]
        })
        
    return jsonify({
        'total_geral': total_geral,
        'bairros_alcançados': len(bairros_data),
        'bairros': bairros_data
    })
