import re
import sqlite3
from db import DB_PATH, gerar_hash


def _conn():
    conn = sqlite3.connect(DB_PATH)
    conn.row_factory = sqlite3.Row
    return conn


def _row(row):
    return dict(row) if row else None


def _rows(rows):
    return [dict(r) for r in rows]


def _slug_username(nome):
    base = (nome or '').strip().lower()
    base = (base.replace('ã','a').replace('á','a').replace('à','a').replace('â','a')
                .replace('é','e').replace('ê','e').replace('í','i').replace('ó','o')
                .replace('õ','o').replace('ô','o').replace('ú','u').replace('ç','c'))
    base = re.sub(r'[^a-z0-9]+', '.', base).strip('.') or 'medico'
    return base


def listar_empresas():
    with _conn() as conn:
        return _rows(conn.execute('''
            SELECT id, nome, COALESCE(email,'') AS email, COALESCE(telefone,'') AS telefone, ativo AS ativa
            FROM empresas
            WHERE ativo = 1
            ORDER BY nome
        ''').fetchall())


def criar_empresa(data):
    nome = (data.get('nome') or '').strip()
    if not nome:
        return {'ok': False, 'erro': 'Nome da empresa obrigatório.'}
    with _conn() as conn:
        cur = conn.execute('''
            INSERT OR IGNORE INTO empresas (nome, email, telefone, ativo)
            VALUES (?, ?, ?, 1)
        ''', (nome, data.get('email',''), data.get('telefone','')))
        conn.commit()
        eid = cur.lastrowid or conn.execute('SELECT id FROM empresas WHERE nome=?', (nome,)).fetchone()[0]
        return _row(conn.execute('SELECT id, nome, email, telefone, ativo AS ativa FROM empresas WHERE id=?', (eid,)).fetchone())


def listar_utentes(empresa_id=None):
    sql = '''
        SELECT
            u.id,
            u.nome,
            COALESCE(u.email,'') AS email,
            COALESCE(u.telefone,'') AS telefone,
            u.empresa_id,
            e.nome AS empresa_nome,
            u.ativo
        FROM utentes u
        LEFT JOIN empresas e ON e.id = u.empresa_id
        WHERE u.ativo = 1
    '''
    params = []
    if empresa_id:
        sql += ' AND u.empresa_id = ?'
        params.append(empresa_id)
    sql += ' ORDER BY u.nome LIMIT 500'
    with _conn() as conn:
        return _rows(conn.execute(sql, params).fetchall())


def criar_utente(data):
    nome = (data.get('nome') or data.get('utente_nome') or '').strip()
    if not nome:
        return {'ok': False, 'erro': 'Nome do utente obrigatório.'}
    with _conn() as conn:
        cur = conn.execute('''
            INSERT INTO utentes (nome, email, telefone, empresa_id, ativo)
            VALUES (?, ?, ?, ?, 1)
        ''', (nome, data.get('email',''), data.get('telefone',''), data.get('empresa_id') or None))
        conn.commit()
        return _row(conn.execute('''
            SELECT u.id, u.nome, u.email, u.telefone, u.empresa_id, e.nome AS empresa_nome, u.ativo
            FROM utentes u
            LEFT JOIN empresas e ON e.id = u.empresa_id
            WHERE u.id=?
        ''', (cur.lastrowid,)).fetchone())


def listar_medicos():
    with _conn() as conn:
        return _rows(conn.execute('''
            SELECT id, nome, username, ativo, '#1a73e8' AS cor
            FROM utilizadores
            WHERE ativo = 1 AND cargo = 'Medico'
            ORDER BY nome
        ''').fetchall())


def criar_medico(data):
    nome = (data.get('nome') or '').strip()
    if not nome:
        return {'ok': False, 'erro': 'Nome do médico obrigatório.'}
    username_base = (data.get('username') or _slug_username(nome)).strip().lower()
    with _conn() as conn:
        row = conn.execute('''
            SELECT id, nome, username, ativo, '#1a73e8' AS cor
            FROM utilizadores
            WHERE cargo='Medico' AND LOWER(nome)=LOWER(?)
            LIMIT 1
        ''', (nome,)).fetchone()
        if row:
            return _row(row)
        username = username_base
        i = 2
        while conn.execute('SELECT id FROM utilizadores WHERE username=?', (username,)).fetchone():
            username = f'{username_base}.{i}'
            i += 1
        cur = conn.execute('''
            INSERT INTO utilizadores (nome, username, password_hash, cargo, ativo)
            VALUES (?, ?, ?, 'Medico', 1)
        ''', (nome, username, gerar_hash(data.get('password') or 'medico_sem_password')))
        conn.commit()
        return _row(conn.execute('''
            SELECT id, nome, username, ativo, '#1a73e8' AS cor
            FROM utilizadores
            WHERE id=?
        ''', (cur.lastrowid,)).fetchone())


def listar_espera():
    # Lista de espera continua no módulo da agenda para não mexer no resto do site.
    from agenda_mod.database import get_connection, rows_to_list
    with get_connection() as conn:
        return rows_to_list(conn.execute('SELECT * FROM lista_espera WHERE ativa=1 ORDER BY prioridade ASC, created_at ASC').fetchall())


def criar_espera(data):
    from agenda_mod.database import get_connection, row_to_dict
    with get_connection() as conn:
        cur = conn.execute('''INSERT INTO lista_espera (utente_id, empresa_id, utente_nome, empresa_nome, telefone, email, medico_preferido, prioridade, observacoes)
                              VALUES (?,?,?,?,?,?,?,?,?)''', (data.get('utente_id'), data.get('empresa_id'), data['utente_nome'].strip(), data.get('empresa_nome',''), data.get('telefone',''), data.get('email',''), data.get('medico_preferido',''), int(data.get('prioridade',2)), data.get('observacoes','')))
        conn.commit()
        return row_to_dict(conn.execute('SELECT * FROM lista_espera WHERE id=?', (cur.lastrowid,)).fetchone())


def remover_espera(item_id):
    from agenda_mod.database import get_connection
    with get_connection() as conn:
        conn.execute('UPDATE lista_espera SET ativa=0 WHERE id=?', (item_id,))
        conn.commit()
    return {'ok': True}
