from flask import Flask, session
import os
import random
import uuid
from datetime import datetime, timedelta
from flask_migrate import Migrate
from sqlalchemy import inspect
from .config import Config
from .models import db, Usuario, Campanha, Pessoa, MetaCadastrador, AuditoriaLog, BairroZona, Politico, CampanhaPolitico

migrate = Migrate()

def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)

    # Initialize extensions
    db.init_app(app)
    migrate.init_app(app, db)

    # Ensure tables exist & auto-seed if empty
    with app.app_context():
        try:
            db.create_all()
            _auto_seed_if_empty()
        except Exception as e:
            print(f"[UNITY Eleitoral] Init DB notice: {e}")

    @app.before_request
    def ensure_tables_exist():
        try:
            inspector = inspect(db.engine)
            if 'usuarios' not in inspector.get_table_names():
                db.create_all()
                _auto_seed_if_empty()
        except Exception as e:
            try:
                db.create_all()
                _auto_seed_if_empty()
            except Exception as ex:
                print(f"[UNITY Eleitoral] before_request db check: {ex}")

    # Favicon fallback route
    @app.route('/favicon.ico')
    def favicon():
        return "", 204

    # Register Blueprints
    from .blueprints.auth import auth_bp
    from .blueprints.campanhas import campanhas_bp
    from .blueprints.usuarios import usuarios_bp
    from .blueprints.cadastros import cadastros_bp
    from .blueprints.dashboards import dashboards_bp
    from .blueprints.rede import rede_bp
    from .blueprints.territorio import territorio_bp
    from .blueprints.relatorios import relatorios_bp
    from .blueprints.api_sync import api_sync_bp
    from .blueprints.auditoria import auditoria_bp

    app.register_blueprint(auth_bp)
    app.register_blueprint(campanhas_bp)
    app.register_blueprint(usuarios_bp)
    app.register_blueprint(cadastros_bp)
    app.register_blueprint(dashboards_bp)
    app.register_blueprint(rede_bp)
    app.register_blueprint(territorio_bp)
    app.register_blueprint(relatorios_bp)
    app.register_blueprint(api_sync_bp)
    app.register_blueprint(auditoria_bp)

    # Global context processors for templates
    @app.context_processor
    def inject_global_vars():
        campanha = None
        current_user = None
        
        if 'campanha_id' in session and session['campanha_id']:
            campanha = db.session.get(Campanha, session['campanha_id'])
            
        if 'usuario_id' in session and session['usuario_id']:
            current_user = db.session.get(Usuario, session['usuario_id'])
            
        pedidos_reset_count = 0
        try:
            pedidos_reset_count = Usuario.query.filter_by(solicitou_reset=True).count()
        except Exception:
            pass
            
        return {
            'app_name': Config.APP_NAME,
            'app_subtitle': Config.APP_SUBTITLE,
            'campanha_ativa': campanha,
            'current_user': current_user,
            'pedidos_reset_count': pedidos_reset_count
        }

    return app

FIRST_NAMES = [
    'Gabriel', 'Lucas', 'Matheus', 'Pedro', 'Guilherme', 'Gustavo', 'Felipe', 'Rafael', 'João', 'Enzo',
    'Arthur', 'Bernardo', 'Heitor', 'Davi', 'Lorenzo', 'Thales', 'Raiam', 'Samuel', 'Diego', 'Bruno',
    'Ana', 'Julia', 'Beatriz', 'Larissa', 'Mariana', 'Camila', 'Amanda', 'Bruna', 'Letícia', 'Isabela',
    'Sophia', 'Alice', 'Helena', 'Laura', 'Manuela', 'Valentina', 'Giovanna', 'Fernanda', 'Patrícia', 'Vanessa'
]

LAST_NAMES = [
    'Silva', 'Santos', 'Oliveira', 'Souza', 'Rodrigues', 'Ferreira', 'Alves', 'Pereira', 'Lima', 'Gomes',
    'Costa', 'Ribeiro', 'Martins', 'Carvalho', 'Almeida', 'Lopes', 'Soares', 'Fernandes', 'Vieira', 'Barbosa',
    'Rocha', 'Dias', 'Nascimento', 'Andrade', 'Moreira', 'Nunes', 'Marques', 'Machado', 'Mendes', 'Freitas'
]

BAIRROS_MANAUS_GEO = [
    ('Cidade Nova', 'Zona Norte', -3.0305, -59.9708, '69090-000'),
    ('Jorge Teixeira', 'Zona Leste', -3.0512, -59.9241, '69088-000'),
    ('Compensa', 'Zona Oeste', -3.1091, -60.0543, '69035-000'),
    ('Alvorada', 'Centro-Oeste', -3.0850, -60.0410, '69042-000'),
    ('Centro', 'Zona Sul', -3.1316, -60.0232, '69005-000'),
    ('São José Operário', 'Zona Leste', -3.0811, -59.9532, '69085-000'),
    ('Coroado', 'Zona Leste', -3.0945, -59.9782, '69080-000'),
    ('Parque 10 de Novembro', 'Centro-Sul', -3.0832, -60.0089, '69055-000'),
    ('Flores', 'Centro-Sul', -3.0645, -60.0156, '69058-000'),
    ('Adrianópolis', 'Centro-Sul', -3.1045, -60.0123, '69057-000'),
    ('Aleixo', 'Centro-Sul', -3.0988, -59.9950, '69060-000'),
    ('Japiim', 'Zona Sul', -3.1150, -59.9850, '69077-000'),
    ('Armando Mendes', 'Zona Leste', -3.0889, -59.9388, '69089-000'),
    ('Nova Cidade', 'Zona Norte', -3.0080, -59.9850, '69097-000'),
    ('Novo Aleixo', 'Zona Leste', -3.0480, -59.9550, '69098-000'),
    ('Santa Etelvina', 'Zona Norte', -2.9910, -59.9950, '69059-000'),
    ('Tarumã', 'Zona Oeste', -3.0350, -60.0850, '69041-000'),
    ('Dom Pedro', 'Centro-Oeste', -3.0920, -60.0380, '69040-000'),
    ('Glória', 'Zona Oeste', -3.1250, -60.0390, '69011-000'),
    ('Educandos', 'Zona Sul', -3.1410, -60.0110, '69070-000')
]

RUAS = [
    'Rua das Palmeiras', 'Avenida Brasil', 'Rua São João', 'Avenida das Torres', 'Rua 7 de Setembro',
    'Alameda Cosme Ferreira', 'Rua Visconde de Porto Alegre', 'Avenida Djalma Batista', 'Rua Recife'
]

def _auto_seed_if_empty():
    """Garante que o banco de dados receba a estrutura limpa e contas iniciais padrão se estiver vazio"""
    try:
        db.create_all()

        if Usuario.query.count() == 0:
            print("[VoxManu] Populando banco com estrutura e usuários padrão...")
            
            # 1. Bairros Zonas
            for b, z, lat, lng, cep in BAIRROS_MANAUS_GEO:
                if not BairroZona.query.filter_by(bairro=b).first():
                    db.session.add(BairroZona(bairro=b, zona=z, lat=lat, lng=lng))

            # 2. Campanha
            campanha = Campanha.query.first()
            if not campanha:
                campanha = Campanha(
                    nome="Projeto Manaus 2026",
                    politico_principal="Marcos Silva",
                    cargo="Deputado Estadual",
                    municipio="Manaus",
                    estado="AM",
                    partido="PMD",
                    coligacao="União pelo Amazonas",
                    meta_total=10000,
                    meta_por_cadastrador=50,
                    slogan="Presença e União pelo Amazonas",
                    data_inicio=datetime.utcnow().date(),
                    ativa=True
                )
                db.session.add(campanha)
                db.session.flush()

            # 3. Políticos
            if Politico.query.first() is None:
                pol_principal = Politico(nome="Marcos Silva", cargo="Deputado Estadual", partido="PMD")
                pol_aliado = Politico(nome="Roberto Santos", cargo="Vereador", partido="PMD")
                db.session.add_all([pol_principal, pol_aliado])
                db.session.flush()

                db.session.add(CampanhaPolitico(campanha_id=campanha.id, politico_id=pol_principal.id, relacao=CampanhaPolitico.REL_PRINCIPAL))
                db.session.add(CampanhaPolitico(campanha_id=campanha.id, politico_id=pol_aliado.id, relacao=CampanhaPolitico.REL_ALIADO))

            # 4. Usuários Padrão para os 4 Perfis do Sistema
            dev = Usuario.query.filter_by(email="dev@unity.com").first()
            if not dev:
                dev = Usuario(nome="Desenvolvedor Superadmin", email="dev@unity.com", perfil=Usuario.ROLE_DEV, campanha_id=campanha.id, primeiro_acesso=False)
                dev.set_senha("dev123")
                db.session.add(dev)

            admin = Usuario.query.filter_by(email="admin@manaus2026.com").first()
            if not admin:
                admin = Usuario(nome="Carlos Administrador", email="admin@manaus2026.com", perfil=Usuario.ROLE_ADMIN, campanha_id=campanha.id, primeiro_acesso=False)
                admin.set_senha("admin123")
                db.session.add(admin)

            vis = Usuario.query.filter_by(email="visualizador@manaus2026.com").first()
            if not vis:
                vis = Usuario(nome="Roberto Visualizador", email="visualizador@manaus2026.com", perfil=Usuario.ROLE_VISUALIZADOR, campanha_id=campanha.id, primeiro_acesso=False)
                vis.set_senha("vis123")
                db.session.add(vis)

            multi = Usuario.query.filter_by(email="multiplicador@manaus2026.com").first()
            if not multi:
                multi = Usuario(
                    nome="João Multiplicador",
                    email="multiplicador@manaus2026.com",
                    perfil=Usuario.ROLE_MULTIPLICADOR,
                    primeiro_acesso=False,
                    campanha_id=campanha.id,
                    criado_por_id=admin.id if admin else None,
                    cadastrador_pai_id=admin.id if admin else None
                )
                multi.set_senha("123456")
                db.session.add(multi)
                db.session.flush()
                db.session.add(MetaCadastrador(cadastrador_id=multi.id, campanha_id=campanha.id, meta=50, quantidade_atual=0))

            db.session.commit()
            print("[VoxManu] SUCCESS: Inicialização limpa concluída sem dados fictícios.")
    except Exception as e:
        db.session.rollback()
        print(f"[VoxManu] ERRO ao executar auto seed: {e}")
