#!/usr/bin/env python3
"""
Inicializa o banco MySQL em uma máquina nova.

Uso:
  python scripts/init_database.py
  python scripts/init_database.py --criar-banco
  python scripts/init_database.py --status
"""

from __future__ import annotations

import argparse
import sys
from pathlib import Path

from dotenv import load_dotenv

BACKEND_DIR = Path(__file__).resolve().parent.parent
REPO_DIR = BACKEND_DIR
if str(BACKEND_DIR) not in sys.path:
    sys.path.insert(0, str(BACKEND_DIR))

load_dotenv(REPO_DIR / ".env")

from sqlalchemy import create_engine, text
from sqlalchemy.engine import URL
from sqlalchemy.exc import OperationalError

from app.db import get_engine, init_db, mysql_habilitado
from app.migrations import run_migrations, status_migrations
from app.settings import (
    MYSQL_ENABLED,
    MYSQL_DATABASE,
    MYSQL_HOST,
    MYSQL_PASSWORD,
    MYSQL_PORT,
    MYSQL_USER,
)


def _url_sem_database() -> str:
    return URL.create(
        drivername="mysql+pymysql",
        username=MYSQL_USER,
        password=MYSQL_PASSWORD,
        host=MYSQL_HOST,
        port=MYSQL_PORT,
        query={"charset": "utf8mb4"},
    ).render_as_string(hide_password=False)


def criar_banco_se_necessario() -> None:
    engine_admin = create_engine(_url_sem_database(), pool_pre_ping=True)
    try:
        with engine_admin.begin() as conn:
            conn.execute(
                text(
                    f"CREATE DATABASE IF NOT EXISTS `{MYSQL_DATABASE}` "
                    "CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"
                )
            )
        print(f"[OK] Banco `{MYSQL_DATABASE}` verificado/criado em {MYSQL_HOST}:{MYSQL_PORT}")
    except OperationalError as erro:
        codigo = getattr(getattr(erro, "orig", None), "args", (None,))[0]
        if codigo == 1044:
            print(
                f"[AVISO] Usuário sem permissão CREATE DATABASE em `{MYSQL_DATABASE}` "
                "(comum em cPanel). Crie o banco no painel e vincule o usuário."
            )
            return
        raise


def _bancos_alvo() -> list[str]:
    """O schema é aplicado uma vez na base compartilhada."""
    return [MYSQL_DATABASE] if MYSQL_DATABASE else []


def main() -> int:
    parser = argparse.ArgumentParser(description="Inicializa schema MySQL do OMRCheck-Web")
    parser.add_argument(
        "--criar-banco",
        action="store_true",
        help="Cria o database MySQL se ainda não existir",
    )
    parser.add_argument(
        "--status",
        action="store_true",
        help="Mostra migrations aplicadas e pendentes",
    )
    args = parser.parse_args()

    if not mysql_habilitado():
        print(
            f"[INFO] MYSQL_ENABLED={MYSQL_ENABLED!r} — "
            "banco MySQL não está habilitado."
        )
        return 0

    if args.criar_banco:
        criar_banco_se_necessario()

    bancos = _bancos_alvo()
    if not bancos:
        print("[ERRO] Nenhum banco configurado (MYSQL_DATABASE).")
        return 1

    for banco in bancos:
        try:
            with get_engine(banco).connect() as conn:
                conn.execute(text("SELECT 1"))
        except Exception as erro:
            print(f"[ERRO] Falha ao conectar em `{banco}`: {erro}")
            return 1

    if args.status:
        for banco in bancos:
            info = status_migrations(get_engine(banco))
            print(f"Banco: {banco}")
            print(f"  Migrations aplicadas ({len(info['aplicadas'])}/{info['total']}): {', '.join(info['aplicadas']) or '—'}")
            if info["pendentes"]:
                print(f"  Pendentes: {', '.join(info['pendentes'])}")
            else:
                print("  Nenhuma migration pendente.")
        return 0

    for banco in bancos:
        executadas = run_migrations(get_engine(banco), verbose=True)
        if executadas:
            print(f"[OK] `{banco}`: {len(executadas)} migration(s): {', '.join(executadas)}")
        else:
            print(f"[OK] `{banco}`: schema já estava atualizado.")

    init_db()
    print("[OK] Banco pronto para uso.")
    print("")
    print("Importante: os dados (cards do Kanban, jobs, sessões) NÃO vêm com o código.")
    print("Na máquina de origem:  python scripts/pacote_migracao.py exportar")
    print("Na máquina nova:      python scripts/pacote_migracao.py importar --arquivo backups\\omrcheck_migracao_....zip")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
