import os
from pathlib import Path
from agenda_mod.database import init_db as init_agenda_db
from agenda_mod.routes.consultas_api import api_bp as agenda_api_bp
from flask import Flask, render_template, render_template_string, request, redirect, url_for, session, send_file, jsonify
from config import Config
from db import (
    testar_ligacao_sqlite,
    executar_schema_sqlite,
    autenticar_utilizador,
    autenticar_medico_por_nome,
    autenticar_enfermeiro_por_nome,
    garantir_dados_iniciais,
    listar_utilizadores,
    criar_utilizador,
    obter_utilizador_por_id,
    alterar_estado_utilizador,
    atualizar_password_utilizador,
    listar_empresas,
    criar_empresa,
    listar_utentes,
    criar_utente,
    desativar_utente,
    listar_medicos_ativos,
    listar_enfermeiros_ativos,
    listar_utentes_para_select,
    criar_marcacao,
    listar_marcacoes,
    cancelar_marcacao,
    concluir_marcacao,
    registar_aptidao,
    obter_marcacao_completa,
    gravar_nota_clinica,
    listar_agenda_dia,
    listar_notas_pendentes,
    listar_fornecedores,
    criar_fornecedor,
    criar_consumivel,
    listar_consumiveis,
    listar_stock_baixo,
    atualizar_stock_consumivel,
    desativar_consumivel,
    listar_consultas_para_consumiveis,
    obter_marcacao_para_consumiveis,
    listar_consumiveis_para_consulta,
    gravar_consumiveis_consulta,
    listar_historico_consumiveis_consulta,
    listar_consumos_para_exportar,
    pesquisar_empresas_utentes,
    listar_utentes_por_empresa,
    pesquisar_utentes_global,
    obter_resumo_empresa,
    obter_detalhe_utente,
    listar_consultas_utente,
    listar_consumos_utente,
    listar_historico_movimentos_stock,
    listar_historico_consumos_geral,
    listar_historico_marcacoes,
    obter_resumo_historico,
    obter_utilizador_por_username,
    atualizar_perfil_ceo,
    listar_fornecedores_com_totais,
    obter_fornecedor_por_id,
    atualizar_fornecedor,
    desativar_fornecedor,
    listar_minhas_consultas,
    obter_resumo_minhas_consultas,
    obter_detalhe_consulta_medico,
    listar_consumiveis_por_categoria,
    obter_consumivel_completo,
    atualizar_consumivel_completo,
    categorias_stock_disponiveis,
    contar_stock_baixo,
    listar_stock_para_excel,
    importar_stock_linhas,
    listar_marcacoes_para_excel,
    listar_reposicao_por_fornecedor,
    listar_produtos_validade_proxima,
    listar_produtos_mais_consumidos,
    listar_ultimos_consumos_dashboard,
    obter_resumo_dashboard_ceo,
    listar_movimentos_stock_completo,
    listar_tipos_movimento_stock,
    listar_utilizadores_admin,
    criar_utilizador_admin,
    alterar_estado_utilizador_admin,
    remover_utilizador_admin,
    atualizar_password_utilizador_admin,
    garantir_tabelas_gestao_equipa,)

app = Flask(__name__)
init_agenda_db()
app.register_blueprint(agenda_api_bp, url_prefix='/agenda-api')
app.config.from_object(Config)

# ── MIGRAÇÕES AUTOMÁTICAS ─────────────────────────────────────
def _migrar_bd():
    """Adiciona colunas novas à BD sem apagar dados existentes."""
    try:
        from db import ligar_mysql
        conn = ligar_mysql(usar_base=True)
        cur  = conn.cursor()
        cur.execute("PRAGMA table_info(marcacoes)")
        colunas = [row[1] for row in cur.fetchall()]
        if "aptidao" not in colunas:
            cur.execute("ALTER TABLE marcacoes ADD COLUMN aptidao TEXT DEFAULT NULL")
            conn.commit()
        if "enfermeiro_id" not in colunas:
            cur.execute("ALTER TABLE marcacoes ADD COLUMN enfermeiro_id INTEGER DEFAULT NULL")
            conn.commit()
        if "local_consulta" not in colunas:
            cur.execute("ALTER TABLE marcacoes ADD COLUMN local_consulta TEXT DEFAULT NULL")
            conn.commit()
        if "convocatoria" not in colunas:
            cur.execute("ALTER TABLE marcacoes ADD COLUMN convocatoria TEXT DEFAULT NULL")
            conn.commit()
        if "clinica_parceira" not in colunas:
            cur.execute("ALTER TABLE marcacoes ADD COLUMN clinica_parceira TEXT DEFAULT NULL")
            conn.commit()
        cur.close()
        conn.close()
    except Exception as e:
        print(f"[migração] aviso: {e}")

_migrar_bd()

@app.template_filter('fmt_data')
def fmt_data(valor):
    if not valor:
        return '—'
    from datetime import datetime
    try:
        return datetime.strptime(str(valor)[:10], '%Y-%m-%d').strftime('%d/%m/%Y')
    except Exception:
        return str(valor)[:10]

@app.template_filter('fmt_hora')
def fmt_hora(valor):
    if not valor:
        return '—'
    return str(valor)[:5]


@app.context_processor
def contexto_alerta_stock():
    total_stock_baixo = 0
    mostrar_alerta_stock = False

    try:
        cargo = session.get("cargo")

        if cargo in ["CEO", "Admin", "Gestor"]:
            total_stock_baixo = contar_stock_baixo()
            confirmado = session.get("stock_alerta_confirmado_total")

            mostrar_alerta_stock = total_stock_baixo > 0 and confirmado != total_stock_baixo

    except Exception:
        total_stock_baixo = 0
        mostrar_alerta_stock = False

    return {
        "total_stock_baixo_alerta": total_stock_baixo,
        "mostrar_alerta_stock": mostrar_alerta_stock
    }


@app.route("/stock-baixo/confirmar")
def confirmar_alerta_stock_baixo():
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin", "Gestor"]:
        return redirect(url_for("dashboard"))

    try:
        session["stock_alerta_confirmado_total"] = contar_stock_baixo()
    except Exception:
        session["stock_alerta_confirmado_total"] = 0

    destino = request.args.get("next") or url_for("dashboard")
    return redirect(destino)



def iniciar_sessao(utilizador):
    session["user_id"] = utilizador["id"]
    session["username"] = utilizador["username"]
    session["nome"] = utilizador["nome"]
    session["cargo"] = utilizador["cargo"]


@app.before_request
def preparar_dados_base():
    # Sem mostrar nada ao utilizador: garante CEO inicial e consumíveis base.
    # Se o SQLite ainda não estiver pronto, ignora para a página não ficar branca.
    try:
        garantir_dados_iniciais()
    except Exception:
        pass


@app.route("/", methods=["GET", "POST"])
def login():
    erro = None

    if request.method == "POST":
        tipo_login = request.form.get("tipo_login", "normal").strip()

        if tipo_login == "medico":
            nome_medico = request.form.get("nome_medico", "").strip()

            if not nome_medico:
                erro = "Escreva o nome do médico."
            else:
                try:
                    medico = autenticar_medico_por_nome(nome_medico)
                except Exception:
                    medico = None
                    erro = "Não foi possível validar o médico. Confirme a ligação à base de dados."

                if medico:
                    iniciar_sessao(medico)
                    return redirect(url_for("dashboard"))

                if not erro:
                    erro = "Esse médico não está registado ou está inativo."

        elif tipo_login == "enfermeiro":
            nome_enfermeiro = request.form.get("nome_enfermeiro", "").strip()

            if not nome_enfermeiro:
                erro = "Escreva o nome do enfermeiro."
            else:
                try:
                    enfermeiro = autenticar_enfermeiro_por_nome(nome_enfermeiro)
                except Exception:
                    enfermeiro = None
                    erro = "Não foi possível validar o enfermeiro. Confirme a ligação à base de dados."

                if enfermeiro:
                    iniciar_sessao(enfermeiro)
                    return redirect(url_for("dashboard"))

                if not erro:
                    erro = "Esse enfermeiro não está registado ou está inativo."

        else:
            username = request.form.get("username", "").strip().lower()
            password = request.form.get("password", "").strip()

            try:
                utilizador = autenticar_utilizador(username, password)
            except Exception:
                utilizador = None
                erro = "Não foi possível ligar à base de dados."
            except Exception:
                utilizador = None
                erro = "Erro ao autenticar o utilizador."

            if utilizador:
                iniciar_sessao(utilizador)
                return redirect(url_for("dashboard"))

            if not erro:
                erro = "Utilizador ou password incorretos."

    return render_template("login.html", erro=erro)


@app.route("/dashboard")
def dashboard():
    if "username" not in session:
        return redirect(url_for("login"))

    cargo = session.get("cargo")

    if cargo == "CEO":
        template = "dashboard_ceo.html"
    elif cargo == "Gestor":
        template = "dashboard_gestor.html"
    elif cargo == "Medico":
        template = "dashboard_medico.html"
    elif cargo == "Enfermeiro":
        template = "dashboard_enfermeiro.html"
    elif cargo == "Admin":
        template = "dashboard_ceo.html"
    else:
        session.clear()
        return redirect(url_for("login"))

    # Carregar KPIs reais para o dashboard
    try:
        from datetime import date
        kpis = obter_resumo_dashboard_ceo()
        ultimos_consumos = listar_ultimos_consumos_dashboard(limit=5)
        consultas_hoje = listar_marcacoes(data=date.today().isoformat())
    except Exception:
        kpis = {}
        ultimos_consumos = []
        consultas_hoje = []

    return render_template(
        template,
        username=session.get("username"),
        nome=session.get("nome"),
        cargo=session.get("cargo"),
        kpis=kpis,
        ultimos_consumos=ultimos_consumos,
        consultas_hoje=consultas_hoje
    )


# Rotas técnicas mantidas, mas sem botões na interface.
@app.route("/sqlite/status")
def sqlite_status():
    if session.get("cargo") != "CEO":
        return redirect(url_for("dashboard") if "username" in session else url_for("login"))

    sucesso, mensagem = testar_ligacao_sqlite()

    return render_template(
        "sqlite_status.html",
        sucesso=sucesso,
        mensagem=mensagem,
        nome=session.get("nome", "CEO"),
        cargo=session.get("cargo", "CEO")
    )


@app.route("/sqlite/inicializar")
def sqlite_inicializar():
    if session.get("cargo") != "CEO":
        return redirect(url_for("dashboard") if "username" in session else url_for("login"))

    caminho_schema = Path(__file__).resolve().parent / "database" / "schema_sqlite.sql"
    sucesso, mensagem = executar_schema_sqlite(caminho_schema)

    return render_template(
        "sqlite_inicializar.html",
        sucesso=sucesso,
        mensagem=mensagem,
        nome=session.get("nome", "CEO"),
        cargo=session.get("cargo", "CEO")
    )








@app.route("/utentes", methods=["GET", "POST"])
def gestao_utentes():
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin"]:
        return redirect(url_for("dashboard"))

    mensagem = None
    erro = None

    if request.method == "POST":
        acao = request.form.get("acao", "").strip()

        if acao == "criar_empresa":
            nome_empresa = request.form.get("nome_empresa", "").strip()
            nif_empresa = request.form.get("nif_empresa", "").strip()
            telefone_empresa = request.form.get("telefone_empresa", "").strip()
            email_empresa = request.form.get("email_empresa", "").strip()
            morada_empresa = request.form.get("morada_empresa", "").strip()

            if not nome_empresa:
                erro = "O nome da empresa é obrigatório."
            else:
                sucesso, resposta = criar_empresa(nome_empresa, nif_empresa, telefone_empresa, email_empresa, morada_empresa)
                if sucesso:
                    mensagem = resposta
                else:
                    erro = resposta

        elif acao == "criar_utente":
            nome_utente = request.form.get("nome", "").strip()

            if not nome_utente:
                erro = "O nome do utente é obrigatório."
            else:
                dados = {
                    "numero_utente": request.form.get("numero_utente", "").strip(),
                    "nome": nome_utente,
                    "data_nascimento": request.form.get("data_nascimento", "").strip(),
                    "sexo": request.form.get("sexo", "").strip(),
                    "numero_identificacao": request.form.get("numero_identificacao", "").strip(),
                    "nif": request.form.get("nif", "").strip(),
                    "telefone": request.form.get("telefone", "").strip(),
                    "email": request.form.get("email", "").strip(),
                    "morada": request.form.get("morada", "").strip(),
                    "codigo_postal": request.form.get("codigo_postal", "").strip(),
                    "localidade": request.form.get("localidade", "").strip(),
                    "empresa_id": request.form.get("empresa_id", "").strip(),
                    "departamento": request.form.get("departamento", "").strip(),
                    "funcao": request.form.get("funcao", "").strip(),
                    "data_admissao": request.form.get("data_admissao", "").strip(),
                    "tipo_exame": request.form.get("tipo_exame", "").strip(),
                    "data_ultimo_exame": request.form.get("data_ultimo_exame", "").strip(),
                    "data_proximo_exame": request.form.get("data_proximo_exame", "").strip(),
                    "observacoes": request.form.get("observacoes", "").strip(),
                }

                sucesso, resposta = criar_utente(dados)

                if sucesso:
                    mensagem = resposta
                else:
                    erro = resposta

    empresas = listar_empresas()
    utentes = listar_utentes()

    return render_template("utentes.html", empresas=empresas, utentes=utentes, mensagem=mensagem, erro=erro, nome=session.get("nome"), cargo=session.get("cargo"))


@app.route("/utentes/<int:utente_id>/remover")
def remover_utente(utente_id):
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin"]:
        return redirect(url_for("dashboard"))

    desativar_utente(utente_id)
    return redirect(url_for("gestao_utentes"))



@app.route("/agenda-full")
def agenda_full():
    if "username" not in session:
        return redirect(url_for("login"))
    if session.get("cargo") not in ["CEO", "Admin", "Gestor"]:
        return redirect(url_for("dashboard"))
    return render_template("agenda_full.html")

@app.route("/marcacoes", methods=["GET", "POST"])
def gestao_marcacoes():
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin", "Gestor"]:
        return redirect(url_for("dashboard"))

    filtro_data = request.args.get("data", "")
    filtro_medico = request.args.get("medico_id", "")
    filtro_estado = request.args.get("estado", "")

    marcacoes = listar_marcacoes(
        data=filtro_data or None,
        medico_id=filtro_medico or None,
        estado=filtro_estado or None
    )
    utentes = listar_utentes_para_select()
    medicos = listar_medicos_ativos()
    enfermeiros = listar_enfermeiros_ativos()

    if request.method == "POST":
        utente_id = request.form.get("utente_id")
        medico_id       = request.form.get("medico_id") or None
        enfermeiro_id   = request.form.get("enfermeiro_id") or None
        data_marcacao   = request.form.get("data_marcacao")
        hora_marcacao   = request.form.get("hora_marcacao")
        tipo_exame      = request.form.get("tipo_exame", "")
        observacoes     = request.form.get("observacoes", "")
        local_consulta  = request.form.get("local_consulta", "") or None
        convocatoria    = request.form.get("convocatoria", "") or None
        clinica_parceira= request.form.get("clinica_parceira", "") or None
        criar_marcacao(utente_id, medico_id, data_marcacao, hora_marcacao,
                       tipo_exame, observacoes, enfermeiro_id,
                       local_consulta, convocatoria, clinica_parceira)
        return redirect(url_for("gestao_marcacoes"))

    from datetime import date
    empresas = listar_empresas()
    return render_template(
        "marcacoes.html",
        nome=session.get("nome"),
        cargo=session.get("cargo"),
        marcacoes=marcacoes,
        utentes=utentes,
        medicos=medicos,
        enfermeiros=enfermeiros,
        empresas=empresas,
        filtro_data=filtro_data,
        filtro_medico=filtro_medico,
        filtro_estado=filtro_estado,
        hoje=date.today().isoformat()
    )


@app.route("/marcacoes/<int:marcacao_id>/cancelar")
def cancelar_marcacao_route(marcacao_id):
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin", "Gestor"]:
        return redirect(url_for("dashboard"))

    cancelar_marcacao(marcacao_id)
    return redirect(url_for("gestao_marcacoes"))


@app.route("/marcacoes/<int:marcacao_id>/concluir")
def concluir_marcacao_route(marcacao_id):
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin", "Gestor"]:
        return redirect(url_for("dashboard"))

    concluir_marcacao(marcacao_id)
    return redirect(url_for("gestao_marcacoes"))


@app.route("/marcacoes/<int:marcacao_id>/aptidao", methods=["POST"])
def registar_aptidao_route(marcacao_id):
    if "username" not in session:
        return redirect(url_for("login"))

    aptidao     = request.form.get("aptidao")
    observacoes = request.form.get("observacoes_aptidao", "").strip() or None
    origem      = request.form.get("origem", "minhas_consultas")

    if aptidao in ("Apto", "Condicionado", "Inapto"):
        registar_aptidao(marcacao_id, aptidao, observacoes)

    if origem == "marcacoes":
        return redirect(url_for("gestao_marcacoes"))
    return redirect(url_for("minhas_consultas"))


@app.route("/consulta/<int:marcacao_id>/nota", methods=["GET", "POST"])
def nota_clinica(marcacao_id):
    if "username" not in session:
        return redirect(url_for("login"))

    marcacao = obter_marcacao_completa(marcacao_id)
    if not marcacao:
        return redirect(url_for("minhas_consultas"))

    mensagem = None
    if request.method == "POST":
        observacoes = request.form.get("observacoes", "").strip()
        gravar_nota_clinica(marcacao_id, observacoes)
        mensagem = "Nota clínica guardada."
        marcacao = obter_marcacao_completa(marcacao_id)

    return render_template(
        "nota_clinica.html",
        marcacao=marcacao,
        mensagem=mensagem,
        nome=session.get("nome"),
        cargo=session.get("cargo")
    )


@app.route("/consumiveis", methods=["GET", "POST"])
def gestao_consumiveis():
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin", "Gestor"]:
        return redirect(url_for("dashboard"))

    mensagem = None
    erro = None
    produto_editar = None

    editar_id = request.args.get("editar", "").strip()

    if editar_id:
        produto_editar = obter_consumivel_completo(editar_id)

    if request.method == "POST":
        acao = request.form.get("acao", "").strip()

        if acao == "criar_fornecedor":
            nome_fornecedor = request.form.get("nome_fornecedor", "").strip()
            email_fornecedor = request.form.get("email_fornecedor", "").strip()
            telefone_fornecedor = request.form.get("telefone_fornecedor", "").strip()
            observacoes_fornecedor = request.form.get("observacoes_fornecedor", "").strip()

            if not nome_fornecedor:
                erro = "O nome do fornecedor é obrigatório."
            else:
                sucesso, resposta = criar_fornecedor(nome_fornecedor, email_fornecedor, telefone_fornecedor, observacoes_fornecedor)
                if sucesso:
                    mensagem = resposta
                else:
                    erro = resposta

        elif acao == "criar_consumivel":
            nome_produto = request.form.get("nome_produto", "").strip()

            if not nome_produto:
                erro = "O nome do consumível é obrigatório."
            else:
                dados = {
                    "codigo": request.form.get("codigo", "").strip(),
                    "categoria": request.form.get("categoria", "").strip(),
                    "nome_produto": nome_produto,
                    "unidade": request.form.get("unidade", "unidade").strip(),
                    "quantidade_stock": request.form.get("quantidade_stock", "0").strip(),
                    "stock_minimo": request.form.get("stock_minimo", "0").strip(),
                    "preco_unitario": request.form.get("preco_unitario", "0").strip().replace(",", "."),
                    "tipo_embalagem": request.form.get("tipo_embalagem", "caixa").strip(),
                    "unidades_por_embalagem": request.form.get("unidades_por_embalagem", "1").strip(),
                    "data_validade": request.form.get("data_validade", "").strip(),
                    "referencia_fornecedor": request.form.get("referencia_fornecedor", "").strip(),
                    "fornecedor_id": request.form.get("fornecedor_id", "").strip(),
                    "observacoes": request.form.get("observacoes", "").strip(),
                }

                try:
                    sucesso, resposta = criar_consumivel(dados)
                    if sucesso:
                        mensagem = resposta
                    else:
                        erro = resposta
                except Exception as e:
                    erro = f"Erro ao criar consumível: {e}"

        elif acao == "editar_consumivel":
            consumivel_id = request.form.get("consumivel_id", "").strip()

            dados = {
                "codigo": request.form.get("codigo", "").strip(),
                "categoria": request.form.get("categoria", "").strip(),
                "nome_produto": request.form.get("nome_produto", "").strip(),
                "unidade": request.form.get("unidade", "unidade").strip(),
                "quantidade_stock": request.form.get("quantidade_stock", "0").strip(),
                "stock_minimo": request.form.get("stock_minimo", "0").strip(),
                "preco_unitario": request.form.get("preco_unitario", "0").strip().replace(",", "."),
                "tipo_embalagem": request.form.get("tipo_embalagem", "caixa").strip(),
                "unidades_por_embalagem": request.form.get("unidades_por_embalagem", "1").strip(),
                "data_validade": request.form.get("data_validade", "").strip(),
                "referencia_fornecedor": request.form.get("referencia_fornecedor", "").strip(),
                "fornecedor_id": request.form.get("fornecedor_id", "").strip(),
                "observacoes": request.form.get("observacoes", "").strip(),
            }

            sucesso, resposta = atualizar_consumivel_completo(consumivel_id, dados, session.get("user_id"))

            if sucesso:
                mensagem = resposta
                produto_editar = None
            else:
                erro = resposta
                produto_editar = obter_consumivel_completo(consumivel_id)

    fornecedores = listar_fornecedores()
    stock_baixo = listar_stock_baixo()
    grupos_consumiveis = listar_consumiveis_por_categoria()
    categorias = categorias_stock_disponiveis()

    return render_template(
        "consumiveis.html",
        fornecedores=fornecedores,
        stock_baixo=stock_baixo,
        grupos_consumiveis=grupos_consumiveis,
        categorias=categorias,
        produto_editar=produto_editar,
        mensagem=mensagem,
        erro=erro,
        nome=session.get("nome"),
        cargo=session.get("cargo")
    )

@app.route("/consumiveis/<int:consumivel_id>/stock", methods=["POST"])
def atualizar_stock_route(consumivel_id):
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin", "Gestor"]:
        return redirect(url_for("dashboard"))

    novo_stock = request.form.get("novo_stock", "").strip()

    if novo_stock:
        atualizar_stock_consumivel(consumivel_id, novo_stock, session.get("user_id"))

    return redirect(url_for("gestao_consumiveis"))




@app.route("/consumiveis/<int:consumivel_id>/movimentar", methods=["POST"])
def movimentar_stock(consumivel_id):
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin", "Gestor"]:
        return redirect(url_for("dashboard"))

    tipo = request.form.get("tipo", "entrada").strip().lower()
    quantidade_txt = request.form.get("quantidade", "0").strip().replace(",", ".")

    try:
        quantidade = int(float(quantidade_txt))
    except Exception:
        quantidade = 0

    if quantidade <= 0:
        return redirect(url_for("gestao_consumiveis"))

    produto = obter_consumivel_completo(consumivel_id)
    if not produto:
        return redirect(url_for("gestao_consumiveis"))

    stock_atual = int(produto.get("quantidade_stock") or 0)

    if tipo in ["saida", "saída"]:
        novo_stock = max(0, stock_atual - quantidade)
    else:
        novo_stock = stock_atual + quantidade

    atualizar_stock_consumivel(consumivel_id, novo_stock, session.get("user_id"))
    return redirect(url_for("gestao_consumiveis"))

@app.route("/consumiveis/<int:consumivel_id>/remover")
def remover_consumivel_route(consumivel_id):
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin"]:
        return redirect(url_for("dashboard"))

    desativar_consumivel(consumivel_id)
    return redirect(url_for("gestao_consumiveis"))




@app.route("/stock/exportar-excel")
def exportar_stock_excel():
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin", "Gestor"]:
        return redirect(url_for("dashboard"))

    try:
        from openpyxl import Workbook
        from openpyxl.styles import Font, PatternFill, Alignment
        from io import BytesIO

        dados = listar_stock_para_excel()

        wb = Workbook()
        ws = wb.active
        ws.title = "Stock COFIHST"

        headers = [
            "codigo",
            "categoria",
            "nome_produto",
            "unidade",
            "quantidade_stock",
            "stock_minimo",
            "preco_unitario",
            "tipo_embalagem",
            "unidades_por_embalagem",
            "data_validade",
            "referencia_fornecedor",
            "fornecedor",
            "fornecedor_email",
            "observacoes",
        ]

        ws.append(headers)

        for cell in ws[1]:
            cell.font = Font(bold=True, color="FFFFFF")
            cell.fill = PatternFill("solid", fgColor="F26A21")
            cell.alignment = Alignment(horizontal="center")

        for row in dados:
            ws.append([
                row.get("codigo"),
                row.get("categoria"),
                row.get("nome_produto"),
                row.get("unidade"),
                row.get("quantidade_stock"),
                row.get("stock_minimo"),
                float(row.get("preco_unitario") or 0),
                row.get("tipo_embalagem"),
                row.get("unidades_por_embalagem"),
                row.get("data_validade"),
                row.get("referencia_fornecedor"),
                row.get("fornecedor"),
                row.get("fornecedor_email"),
                row.get("observacoes"),
            ])

        for column_cells in ws.columns:
            max_length = 0
            col_letter = column_cells[0].column_letter

            for cell in column_cells:
                value = str(cell.value) if cell.value is not None else ""
                max_length = max(max_length, len(value))

            ws.column_dimensions[col_letter].width = min(max_length + 3, 42)

        output = BytesIO()
        wb.save(output)
        output.seek(0)

        return send_file(
            output,
            as_attachment=True,
            download_name="stock_cofihst.xlsx",
            mimetype="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
        )

    except ModuleNotFoundError:
        return "Falta instalar openpyxl. No terminal: pip install openpyxl", 500


@app.route("/stock/importar-excel", methods=["GET", "POST"])
def importar_stock_excel():
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin", "Gestor"]:
        return redirect(url_for("dashboard"))

    mensagem = None
    erro = None

    if request.method == "POST":
        ficheiro = request.files.get("ficheiro_excel")

        if not ficheiro or not ficheiro.filename:
            erro = "Selecione um ficheiro Excel."
        else:
            try:
                from openpyxl import load_workbook

                wb = load_workbook(ficheiro, data_only=True)
                ws = wb.active

                headers = []
                for cell in ws[1]:
                    headers.append(str(cell.value).strip() if cell.value is not None else "")

                linhas = []

                for row in ws.iter_rows(min_row=2, values_only=True):
                    item = {}

                    for idx, header in enumerate(headers):
                        if not header:
                            continue

                        item[header] = row[idx] if idx < len(row) else None

                    linhas.append(item)

                resultado = importar_stock_linhas(linhas, session.get("user_id"))

                mensagem = (
                    f"Importação concluída. "
                    f"Criados: {resultado['criados']}. "
                    f"Atualizados: {resultado['atualizados']}. "
                    f"Ignorados: {resultado['ignorados']}."
                )

            except ModuleNotFoundError:
                erro = "Falta instalar openpyxl. No terminal: pip install openpyxl"
            except Exception as e:
                erro = f"Erro ao importar Excel: {e}"

    return render_template(
        "importar_stock.html",
        mensagem=mensagem,
        erro=erro,
        nome=session.get("nome"),
        cargo=session.get("cargo")
    )









@app.route("/marcacoes/exportar-excel")
def exportar_marcacoes_excel():
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin", "Gestor"]:
        return redirect(url_for("dashboard"))

    try:
        from openpyxl import Workbook
        from openpyxl.styles import Font, PatternFill, Alignment
        from io import BytesIO

        data_inicio = request.args.get("data_inicio") or None
        data_fim    = request.args.get("data_fim")    or None
        estado      = request.args.get("estado")      or None

        dados = listar_marcacoes_para_excel(data_inicio, data_fim, estado)

        wb = Workbook()
        ws = wb.active
        ws.title = "Marcações COFIHST"

        headers = [
            "id", "data_marcacao", "hora_marcacao", "tipo_exame",
            "estado", "aptidao", "utente", "numero_utente", "empresa",
            "medico", "enfermeiro", "local_consulta", "convocatoria",
            "clinica_parceira", "observacoes",
        ]
        ws.append(headers)

        for cell in ws[1]:
            cell.font = Font(bold=True, color="FFFFFF")
            cell.fill = PatternFill("solid", fgColor="1478D4")
            cell.alignment = Alignment(horizontal="center")

        for row in dados:
            ws.append([row.get(h) for h in headers])

        for column_cells in ws.columns:
            max_length = max((len(str(c.value)) if c.value is not None else 0) for c in column_cells)
            ws.column_dimensions[column_cells[0].column_letter].width = min(max_length + 3, 42)

        output = BytesIO()
        wb.save(output)
        output.seek(0)

        return send_file(
            output,
            as_attachment=True,
            download_name="marcacoes_cofihst.xlsx",
            mimetype="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
        )

    except ModuleNotFoundError:
        return "Falta instalar openpyxl. No terminal: pip install openpyxl", 500


@app.route("/movimentos-stock")
def movimentos_stock_page():
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin", "Gestor"]:
        return redirect(url_for("dashboard"))

    termo = request.args.get("q", "").strip()
    tipo = request.args.get("tipo", "").strip()

    movimentos = listar_movimentos_stock_completo(termo=termo, tipo=tipo)
    tipos = listar_tipos_movimento_stock()

    return render_template(
        "movimentos_stock.html",
        movimentos=movimentos,
        tipos=tipos,
        termo=termo,
        tipo=tipo,
        nome=session.get("nome"),
        cargo=session.get("cargo")
    )

@app.route("/stock/email-reposicao")
def email_reposicao_stock():
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin", "Gestor"]:
        return redirect(url_for("dashboard"))

    grupos = listar_reposicao_por_fornecedor()

    return render_template(
        "email_reposicao.html",
        grupos=grupos,
        nome=session.get("nome"),
        cargo=session.get("cargo")
    )

@app.route("/stock-baixo")
def stock_baixo_page():
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin", "Gestor"]:
        return redirect(url_for("dashboard"))

    stock_baixo = listar_stock_baixo()

    return render_template("stock_baixo.html", stock_baixo=stock_baixo, nome=session.get("nome"), cargo=session.get("cargo"))


@app.route("/consumiveis-consulta", methods=["GET", "POST"])
def consumiveis_consulta():
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin", "Medico", "Enfermeiro"]:
        return redirect(url_for("dashboard"))

    mensagem = None
    erro = None
    marcacao_selecionada = None

    marcacao_id = request.args.get("marcacao_id", "").strip()

    if request.method == "POST":
        marcacao_id = request.form.get("marcacao_id", "").strip()
        consumivel_ids = request.form.getlist("consumivel_id[]")
        quantidades = request.form.getlist("quantidade[]")

        itens = []
        for consumivel_id, quantidade in zip(consumivel_ids, quantidades):
            if consumivel_id and quantidade:
                itens.append({"consumivel_id": consumivel_id, "quantidade": quantidade})

        sucesso, resposta = gravar_consumiveis_consulta(marcacao_id, itens, session.get("user_id"), session.get("cargo"))

        if sucesso:
            mensagem = resposta
            marcacao_id = ""
        else:
            erro = resposta

    consultas = listar_consultas_para_consumiveis(session.get("cargo"), session.get("user_id"))
    consumiveis = listar_consumiveis_para_consulta()
    historico = listar_historico_consumiveis_consulta(session.get("cargo"), session.get("user_id"))

    if marcacao_id:
        marcacao_selecionada = obter_marcacao_para_consumiveis(marcacao_id, session.get("cargo"), session.get("user_id"))
        if not marcacao_selecionada:
            erro = "Consulta não encontrada, sem permissão ou já concluída."

    import datetime
    hoje = datetime.date.today()

    return render_template("consumiveis_consulta.html", consultas=consultas, consumiveis=consumiveis, historico=historico, marcacao_selecionada=marcacao_selecionada, mensagem=mensagem, erro=erro, nome=session.get("nome"), cargo=session.get("cargo"), now_mes=hoje.month, now_ano=hoje.year)


@app.route("/consumiveis-consulta/exportar-excel")
def exportar_consumos_consulta_excel():
    if "username" not in session:
        return redirect(url_for("login"))

    try:
        from openpyxl import Workbook
        from openpyxl.styles import Font, PatternFill, Alignment
        from io import BytesIO
        import datetime

        hoje = datetime.date.today()
        ano = int(request.args.get("ano", hoje.year))
        mes = int(request.args.get("mes", hoje.month))

        dados = listar_consumos_para_exportar(session.get("cargo"), session.get("user_id"), ano, mes)

        nome_mes = ["Janeiro","Fevereiro","Março","Abril","Maio","Junho",
                    "Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"][mes - 1]

        wb = Workbook()
        ws = wb.active
        ws.title = f"Consumos {nome_mes} {ano}"

        headers = ["Data", "Utente", "Empresa", "Médico", "Produto", "Quantidade", "Unidade", "Preço Unitário (€)"]
        ws.append(headers)

        for cell in ws[1]:
            cell.font = Font(bold=True, color="FFFFFF")
            cell.fill = PatternFill("solid", fgColor="1478D4")
            cell.alignment = Alignment(horizontal="center")

        campos = ["data", "utente", "empresa", "medico", "produto", "quantidade", "unidade", "preco_unitario"]
        for row in dados:
            ws.append([row.get(c) for c in campos])

        for column_cells in ws.columns:
            max_length = max((len(str(c.value)) if c.value is not None else 0) for c in column_cells)
            ws.column_dimensions[column_cells[0].column_letter].width = min(max_length + 3, 40)

        output = BytesIO()
        wb.save(output)
        output.seek(0)

        return send_file(
            output,
            as_attachment=True,
            download_name=f"consumos_{nome_mes}_{ano}.xlsx",
            mimetype="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
        )

    except ModuleNotFoundError:
        return "Falta instalar openpyxl. No terminal: pip install openpyxl", 500


@app.route("/api/utentes-por-empresa/<int:empresa_id>")
def api_utentes_por_empresa(empresa_id):
    if "username" not in session:
        return jsonify([]), 401
    utentes = listar_utentes_por_empresa(empresa_id)
    return jsonify([{"id": u["id"], "nome": u["nome"], "numero": u.get("numero_utente", "")} for u in utentes])



    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin", "Gestor", "Medico"]:
        return redirect(url_for("dashboard"))

    termo = request.args.get("q", "").strip()
    empresa_id = request.args.get("empresa_id", "").strip()
    utente_id = request.args.get("utente_id", "").strip()
    ver_todos = request.args.get("ver_todos", "").strip() == "1"

    pesquisou = bool(termo or empresa_id or utente_id or ver_todos)

    # Ao abrir sem pesquisa, mostra a mesma página unificada, sem templates antigos nem menus duplicados.
    if not pesquisou:
        return render_template(
            "pesquisar_utentes.html",
            pesquisou=False,
            ver_todos=False,
            termo="",
            empresa_id="",
            utente_id="",
            empresas=[],
            utentes=[],
            resumo_empresa=None,
            utentes_empresa=[],
            utente=None,
            consultas_utente=[],
            consumos_utente=[],
            nome=session.get("nome"),
            cargo=session.get("cargo")
        )

    empresas = []
    utentes = []
    resumo_empresa = None
    utentes_empresa = []
    utente = None
    consultas_utente = []
    consumos_utente = []

    if session.get("cargo") in ["CEO", "Admin", "Gestor"]:
        if ver_todos:
            # Mostra todos os utentes sem listar todas as empresas automaticamente.
            utentes = pesquisar_utentes_global("")
        elif termo:
            empresas = pesquisar_empresas_utentes(termo)
            utentes = pesquisar_utentes_global(termo)

        if empresa_id:
            resumo_empresa = obter_resumo_empresa(empresa_id)
            utentes_empresa = listar_utentes_por_empresa(empresa_id)

    else:
        if ver_todos:
            utentes = pesquisar_utentes_global("")
        elif termo:
            utentes = pesquisar_utentes_global(termo)

    if utente_id:
        utente = obter_detalhe_utente(utente_id)
        consultas_utente = listar_consultas_utente(utente_id)
        consumos_utente = listar_consumos_utente(utente_id)

    return render_template(
        "pesquisar_utentes.html",
        pesquisou=True,
        ver_todos=ver_todos,
        termo=termo,
        empresa_id=empresa_id,
        utente_id=utente_id,
        empresas=empresas,
        utentes=utentes,
        resumo_empresa=resumo_empresa,
        utentes_empresa=utentes_empresa,
        utente=utente,
        consultas_utente=consultas_utente,
        consumos_utente=consumos_utente,
        nome=session.get("nome"),
        cargo=session.get("cargo")
    )

@app.route("/historico")
def historico_geral():
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin", "Gestor"]:
        return redirect(url_for("dashboard"))

    resumo = obter_resumo_historico()
    movimentos_stock = listar_historico_movimentos_stock()
    consumos = listar_historico_consumos_geral()
    marcacoes = listar_historico_marcacoes()

    return render_template("historico.html", resumo=resumo, movimentos_stock=movimentos_stock, consumos=consumos, marcacoes=marcacoes, nome=session.get("nome"), cargo=session.get("cargo"))


@app.route("/perfil-ceo", methods=["GET", "POST"])
def perfil_ceo():
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") != "CEO":
        return redirect(url_for("dashboard"))

    mensagem = None
    erro = None
    utilizador = obter_utilizador_por_username(session.get("username"))

    if not utilizador:
        session.clear()
        return redirect(url_for("login"))

    if request.method == "POST":
        novo_nome = request.form.get("nome", "").strip()
        novo_username = request.form.get("username", "").strip().lower()
        password_atual = request.form.get("password_atual", "").strip()
        nova_password = request.form.get("nova_password", "").strip()
        confirmar_password = request.form.get("confirmar_password", "").strip()

        sucesso, resposta = atualizar_perfil_ceo(session.get("user_id"), novo_nome, novo_username, password_atual, nova_password, confirmar_password)

        if sucesso:
            mensagem = resposta
            session["nome"] = novo_nome
            session["username"] = novo_username
            utilizador = obter_utilizador_por_username(novo_username)
        else:
            erro = resposta

    return render_template("perfil_ceo.html", utilizador=utilizador, mensagem=mensagem, erro=erro, nome=session.get("nome"), cargo=session.get("cargo"))


@app.route("/fornecedores", methods=["GET", "POST"])
def fornecedores_page():
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin", "Gestor"]:
        return redirect(url_for("dashboard"))

    mensagem = None
    erro = None
    fornecedor_editar = None
    editar_id = request.args.get("editar", "").strip()

    if editar_id:
        fornecedor_editar = obter_fornecedor_por_id(editar_id)

    if request.method == "POST":
        acao = request.form.get("acao", "").strip()

        if acao == "criar":
            nome_fornecedor = request.form.get("nome", "").strip()
            email_fornecedor = request.form.get("email", "").strip()
            telefone_fornecedor = request.form.get("telefone", "").strip()
            observacoes_fornecedor = request.form.get("observacoes", "").strip()

            if not nome_fornecedor:
                erro = "O nome do fornecedor é obrigatório."
            else:
                sucesso, resposta = criar_fornecedor(nome_fornecedor, email_fornecedor, telefone_fornecedor, observacoes_fornecedor)
                if sucesso:
                    mensagem = resposta
                else:
                    erro = resposta

        elif acao == "editar":
            fornecedor_id = request.form.get("fornecedor_id", "").strip()
            nome_fornecedor = request.form.get("nome", "").strip()
            email_fornecedor = request.form.get("email", "").strip()
            telefone_fornecedor = request.form.get("telefone", "").strip()
            observacoes_fornecedor = request.form.get("observacoes", "").strip()

            sucesso, resposta = atualizar_fornecedor(fornecedor_id, nome_fornecedor, email_fornecedor, telefone_fornecedor, observacoes_fornecedor)

            if sucesso:
                mensagem = resposta
                fornecedor_editar = None
            else:
                erro = resposta

    fornecedores = listar_fornecedores_com_totais()

    return render_template("fornecedores.html", fornecedores=fornecedores, fornecedor_editar=fornecedor_editar, mensagem=mensagem, erro=erro, nome=session.get("nome"), cargo=session.get("cargo"))


@app.route("/fornecedores/<int:fornecedor_id>/remover")
def remover_fornecedor_route(fornecedor_id):
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") not in ["CEO", "Admin"]:
        return redirect(url_for("dashboard"))

    desativar_fornecedor(fornecedor_id)
    return redirect(url_for("fornecedores_page"))


@app.route("/minhas-consultas")
def minhas_consultas():
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") != "Medico":
        return redirect(url_for("dashboard"))

    estado = request.args.get("estado", "").strip()
    marcacao_id = request.args.get("marcacao_id", "").strip()

    consultas = listar_minhas_consultas(session.get("user_id"), estado)
    resumo = obter_resumo_minhas_consultas(session.get("user_id"))
    consulta_selecionada = None

    if marcacao_id:
        consulta_selecionada = obter_detalhe_consulta_medico(marcacao_id, session.get("user_id"))

    return render_template("minhas_consultas.html", consultas=consultas, resumo=resumo, estado=estado, consulta_selecionada=consulta_selecionada, nome=session.get("nome"), cargo=session.get("cargo"))


@app.route("/consultas-do-dia")
def consultas_do_dia():
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") != "Enfermeiro":
        return redirect(url_for("dashboard"))

    from datetime import date
    consultas = listar_marcacoes(data=date.today().isoformat())

    return render_template(
        "consultas_do_dia.html",
        consultas=consultas,
        nome=session.get("nome"),
        cargo=session.get("cargo"),
    )


@app.route("/modulo/<nome_modulo>")
def modulo_placeholder(nome_modulo):
    if "username" not in session:
        return redirect(url_for("login"))

    return redirect(url_for("dashboard"))


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




@app.route("/utilizadores", methods=["GET", "POST"])
def gestao_utilizadores():
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") != "CEO":
        return redirect(url_for("dashboard"))

    garantir_tabelas_gestao_equipa()

    mensagem = None
    erro = None

    if request.method == "POST":
        nome_form = request.form.get("nome")
        username_form = request.form.get("username")
        password_form = request.form.get("password")
        cargo_form = request.form.get("cargo")

        ok, resposta = criar_utilizador_admin(nome_form, username_form, password_form, cargo_form)
        if ok:
            mensagem = resposta
        else:
            erro = resposta

    utilizadores = listar_utilizadores_admin()

    return render_template(
        "utilizadores.html",
        utilizadores=utilizadores,
        mensagem=mensagem,
        erro=erro,
        nome=session.get("nome"),
        cargo=session.get("cargo"),
        user_id=session.get("user_id")
    )


@app.route("/utilizadores/<int:user_id>/estado/<int:ativo>")
def alterar_estado_user(user_id, ativo):
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") != "CEO":
        return redirect(url_for("dashboard"))

    alterar_estado_utilizador_admin(user_id, ativo)
    return redirect(url_for("gestao_utilizadores"))


@app.route("/utilizadores/<int:user_id>/remover")
def remover_utilizador_route(user_id):
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") != "CEO":
        return redirect(url_for("dashboard"))

    remover_utilizador_admin(user_id)
    return redirect(url_for("gestao_utilizadores"))


@app.route("/utilizadores/<int:user_id>/password", methods=["POST"])
def reset_password_user(user_id):
    if "username" not in session:
        return redirect(url_for("login"))

    if session.get("cargo") != "CEO":
        return redirect(url_for("dashboard"))

    nova_password = request.form.get("nova_password")
    atualizar_password_utilizador_admin(user_id, nova_password)
    return redirect(url_for("gestao_utilizadores"))




@app.route("/agenda-dia")
def agenda_dia():
    if "username" not in session:
        return redirect(url_for("login"))

    from datetime import date, timedelta
    hoje = date.today().isoformat()
    data = request.args.get("data", hoje)
    medico_id = request.args.get("medico_id", "")

    marcacoes = listar_agenda_dia(data, medico_id or None)
    medicos   = listar_medicos_ativos()
    notas     = listar_notas_pendentes()

    # Agrupar por médico
    por_medico = {}
    for m in marcacoes:
        nome_med = m["medico"] or "Sem médico"
        por_medico.setdefault(nome_med, []).append(m)

    # Datas prev/next
    d = date.fromisoformat(data)
    data_ant = (d - timedelta(days=1)).isoformat()
    data_seg = (d + timedelta(days=1)).isoformat()

    return render_template(
        "agenda_dia.html",
        data=data,
        data_ant=data_ant,
        data_seg=data_seg,
        por_medico=por_medico,
        marcacoes=marcacoes,
        medicos=medicos,
        notas=notas,
        medico_id_sel=medico_id,
        nome=session.get("nome"),
        cargo=session.get("cargo")
    )

if __name__ == "__main__":
    app.run(debug=True)
